/* packet-solaredge.c
 * Dissector routines for the SolarEdge monitoring protocol
 * By Erik de Jong <erikdejong@gmail.com>
 * Copyright 2017 Erik de Jong
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "config.h"
#include <epan/conversation.h>
#include <epan/expert.h>
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/strutil.h>
#include <epan/tfs.h>
#include <epan/unit_strings.h>

#include <wsutil/array.h>
#include <wsutil/crc16-plain.h>
#include <wsutil/wsgcrypt.h>

#define SOLAREDGE_MAGIC_NUMBER			0x79563412
#define SOLAREDGE_ENCRYPTION_KEY_LENGTH		16
#define SOLAREDGE_HEADER_LENGTH			20
#define SOLAREDGE_POST_HEADER_LENGTH		8

#define SOLAREDGE_COMMAND_PARAMS_RESET						0x0010
#define SOLAREDGE_COMMAND_PARAMS_SET_SINGLE					0x0011
#define SOLAREDGE_COMMAND_PARAMS_GET_SINGLE					0x0012
#define SOLAREDGE_COMMAND_PARAMS_GET_INFO					0x0013
#define SOLAREDGE_COMMAND_PARAMS_GET_NAME					0x0014
#define SOLAREDGE_COMMAND_PARAMS_GET_NUM					0x0015
#define SOLAREDGE_COMMAND_PARAMS_GET_ALL					0x0016
#define SOLAREDGE_COMMAND_PARAMS_SET_ALL					0x0017
#define SOLAREDGE_COMMAND_PARAMS_SET_SINGLE_NOSAVE				0x0018
#define SOLAREDGE_COMMAND_PARAMS_SAVE						0x0019
#define SOLAREDGE_COMMAND_PARAMS_POLICY_ENABLE					0x001a
#define SOLAREDGE_COMMAND_PARAMS_POLICY_DISABLE					0x001b
#define SOLAREDGE_COMMAND_PARAMS_POLICY_DISABLE_VOLATILE			0x001c
#define SOLAREDGE_COMMAND_PARAMS_SET_POLICY_PASSWORD				0x001d
#define SOLAREDGE_COMMAND_PARAMS_GET_VOLATILE					0x001e
#define SOLAREDGE_COMMAND_PARAMS_SET_VOLATILE					0x001f
#define SOLAREDGE_COMMAND_UPGRADE_START						0x0020
#define SOLAREDGE_COMMAND_UPGRADE_WRITE						0x0021
#define SOLAREDGE_COMMAND_UPGRADE_FINISH					0x0022
#define SOLAREDGE_COMMAND_UPGRADE_READ_DATA					0x0023
#define SOLAREDGE_COMMAND_UPGRADE_READ_SIZE					0x0024
#define SOLAREDGE_COMMAND_MISC_RESET						0x0030
#define SOLAREDGE_COMMAND_MISC_STOP						0x0031
#define SOLAREDGE_COMMAND_MISC_DUMMY						0x0032
#define SOLAREDGE_COMMAND_MISC_GET_VER						0x0033
#define SOLAREDGE_COMMAND_MISC_GET_TYPE						0x0034
#define SOLAREDGE_COMMAND_MISC_PAYLOAD						0x0035
#define SOLAREDGE_COMMAND_MISC_SET_ID						0x0036
#define SOLAREDGE_COMMAND_MISC_READ_MEMORY					0x0037
#define SOLAREDGE_COMMAND_MISC_PARAMS_PARTIAL_RESET				0x0038
#define SOLAREDGE_COMMAND_MISC_GET_MAX_PACKET_SIZE				0x0039
#define SOLAREDGE_COMMAND_MISC_ENCRYPTED					0x003d
#define SOLAREDGE_COMMAND_PARAMS_SMART_LOAD_PARAMS				0x0040
#define SOLAREDGE_COMMAND_MISC_PARAMS_PARTIAL_RESET2				0x0041
#define SOLAREDGE_COMMAND_PARAMS_IGNORE_PARAMS_LIST				0x0042
#define SOLAREDGE_COMMAND_PARAMS_PARTIAL_RESET_AS_LEVEL				0x0043
#define SOLAREDGE_COMMAND_PARAMS_PARTIAL_RESET_PCB_LEVEL			0x0044
#define SOLAREDGE_COMMAND_RESP_ACK						0x0080
#define SOLAREDGE_COMMAND_RESP_NACK						0x0081
#define SOLAREDGE_COMMAND_RESP_PARAMS_SINGLE					0x0090
#define SOLAREDGE_COMMAND_RESP_PARAMS_INFO					0x0091
#define SOLAREDGE_COMMAND_RESP_PARAMS_NAME					0x0092
#define SOLAREDGE_COMMAND_RESP_PARAMS_NUM					0x0093
#define SOLAREDGE_COMMAND_RESP_PARAMS_ALL					0x0094
#define SOLAREDGE_COMMAND_RESP_PARAMS_INCORRECT_PASSWORD			0x0095
#define SOLAREDGE_COMMAND_RESP_UPGRADE_DATA					0x00a0
#define SOLAREDGE_COMMAND_RESP_UPGRADE_SIZE					0x00a1
#define SOLAREDGE_COMMAND_RESP_MISC_GET_VER					0x00b0
#define SOLAREDGE_COMMAND_RESP_MISC_GET_TYPE					0x00b1
#define SOLAREDGE_COMMAND_RESP_MISC_PAYLOAD					0x00b2
#define SOLAREDGE_COMMAND_RESP_MISC_READ_MEMORY					0x00b3
#define SOLAREDGE_COMMAND_RESP_MISC_GET_MAX_PACKET_SIZE				0x00b4
#define SOLAREDGE_COMMAND_MERCURY_PWM_SET					0x0100
#define SOLAREDGE_COMMAND_MERCURY_PWM_ENABLE					0x0101
#define SOLAREDGE_COMMAND_MERCURY_A2D_SAMPLE					0x0102
#define SOLAREDGE_COMMAND_MERCURY_KA						0x0103
#define SOLAREDGE_COMMAND_MERCURY_SET_VIREF					0x0104
#define SOLAREDGE_COMMAND_MERCURY_SET_VOMAXREF					0x0105
#define SOLAREDGE_COMMAND_MERCURY_SET_VOMINREF					0x0106
#define SOLAREDGE_COMMAND_MERCURY_READ_MEAS					0x0107
#define SOLAREDGE_COMMAND_MERCURY_CLOSED_LOOP_START				0x0108
#define SOLAREDGE_COMMAND_MERCURY_OPEN_LOOP_START				0x0109
#define SOLAREDGE_COMMAND_MERCURY_OPEN_LOOP_SET					0x010a
#define SOLAREDGE_COMMAND_MERCURY_SET_12V_10V					0x010b
#define SOLAREDGE_COMMAND_MERCURY_SET_5V_35V					0x010c
#define SOLAREDGE_COMMAND_MERCURY_SET_VO_RANGE					0x010d
#define SOLAREDGE_COMMAND_MERCURY_START_MPPT					0x010e
#define SOLAREDGE_COMMAND_MERCURY_TX_ENABLE					0x010f
#define SOLAREDGE_COMMAND_MERCURY_TX_TEST					0x0110
#define SOLAREDGE_COMMAND_MERCURY_RX_TEST					0x0111
#define SOLAREDGE_COMMAND_MERCURY_FORCE_TELEM					0x0112
#define SOLAREDGE_COMMAND_MERCURY_READ_SAMPLES_DIRECT				0x0113
#define SOLAREDGE_COMMAND_MERCURY_SET_OTP_BLOCK					0x0114
#define SOLAREDGE_COMMAND_MERCURY_SET_CAL_MODE					0x0115
#define SOLAREDGE_COMMAND_MERCURY_SET_VI_RANGE					0x0116
#define SOLAREDGE_COMMAND_MERCURY_AVG_SAMPLE					0x0117
#define SOLAREDGE_COMMAND_MERCURY_GET_TELEM					0x0118
#define SOLAREDGE_COMMAND_MERCURY_DISABLE_PROTECTION				0x0119
#define SOLAREDGE_COMMAND_MERCURY_BYPASS_MODE					0x011a
#define SOLAREDGE_COMMAND_MERCURY_SET_TEMP_CAL_PIN				0x011b
#define SOLAREDGE_COMMAND_MERCURY_SAVE_VOLATILE					0x011c
#define SOLAREDGE_COMMAND_MERCURY_BBB_MODE					0x011d
#define SOLAREDGE_COMMAND_MERCURY_GET_REG					0x011e
#define SOLAREDGE_COMMAND_MERCURY_SET_RES_CIRC_GPIOS				0x011f
#define SOLAREDGE_COMMAND_MERCURY_GET_SNR					0x0120
#define SOLAREDGE_COMMAND_MERCURY_GET_LOOP_MODE					0x0121
#define SOLAREDGE_COMMAND_MERCURY_SET_REG					0x0122
#define SOLAREDGE_COMMAND_MERCURY_DFT						0x0123
#define SOLAREDGE_COMMAND_MERCURY_SET_COMM_SW					0x0124
#define SOLAREDGE_COMMAND_MERCURY_GET_SPI_SAMPLES				0x0125
#define SOLAREDGE_COMMAND_MERCURY_SET_DT					0x0126
#define SOLAREDGE_COMMAND_MERCURY_GET_DFT_AVG					0x0127
#define SOLAREDGE_COMMAND_MERCURY_CONTROL_TEST					0x0128
#define SOLAREDGE_COMMAND_MERCURY_GET_STATUS_REG				0x0129
#define SOLAREDGE_COMMAND_MERCURY_RESET_STATUS_REG				0x012a
#define SOLAREDGE_COMMAND_MERCURY_SET_DPWM_FREQ					0x012b
#define SOLAREDGE_COMMAND_RESP_MERCURY_SAMPLES					0x0180
#define SOLAREDGE_COMMAND_RESP_MERCURY_MON					0x0181
#define SOLAREDGE_COMMAND_RESP_MERCURY_TELEM					0x0182
#define SOLAREDGE_COMMAND_RESP_MERCURY_MEAS					0x0183
#define SOLAREDGE_COMMAND_RESP_MERCURY_RX_TEST_RES				0x0184
#define SOLAREDGE_COMMAND_RESP_MERCURY_SAMPLES_DIRECT				0x0185
#define SOLAREDGE_COMMAND_RESP_MERCURY_AVG_SAMPLE				0x0186
#define SOLAREDGE_COMMAND_RESP_MERCURY_GET_TELEM				0x0187
#define SOLAREDGE_COMMAND_RESP_MERCURY_CONTROL_TEST				0x0188
#define SOLAREDGE_COMMAND_VENUSMNGR_READ_ISE_MEAS1				0x0200
#define SOLAREDGE_COMMAND_VENUSMNGR_READ_ISE_MEAS2				0x0201
#define SOLAREDGE_COMMAND_VENUSMNGR_READ_SE_MEAS				0x0202
#define SOLAREDGE_COMMAND_VENUSMNGR_START_INVERTER				0x0203
#define SOLAREDGE_COMMAND_VENUSMNGR_ISE_DUTY_CYCLE				0x0204
#define SOLAREDGE_COMMAND_VENUSMNGR_GET_SYS_STATUS				0x0205
#define SOLAREDGE_COMMAND_VENUSMNGR_GET_TELEM					0x0206
#define SOLAREDGE_COMMAND_VENUSMNGR_RX_TEST_INIT				0x0207
#define SOLAREDGE_COMMAND_VENUSMNGR_RX_TEST					0x0208
#define SOLAREDGE_COMMAND_VENUSMNGR_TX_TEST_START				0x0209
#define SOLAREDGE_COMMAND_VENUSMNGR_TX_TEST_STOP				0x020a
#define SOLAREDGE_COMMAND_VENUSMNGR_SET_TX_ENABLE				0x020b
#define SOLAREDGE_COMMAND_VENUSMNGR_ENABLE_ISE_WD				0x020c
#define SOLAREDGE_COMMAND_VENUSMNGR_DISABLE_ISE_WD				0x020d
#define SOLAREDGE_COMMAND_VENUSMNGR_GET_COUNTRY_CODE				0x020e
#define SOLAREDGE_COMMAND_VENUSMNGR_SET_COUNTRY					0x020f
#define SOLAREDGE_COMMAND_VENUSMNGR_PRIVILEGED_MODE				0x0210
#define SOLAREDGE_COMMAND_VENUSMNGR_PRIVILEGED_SET_PARAM			0x0211
#define SOLAREDGE_COMMAND_VENUSMNGR_PRIVILEGED_GET_EVENT			0x0212
#define SOLAREDGE_COMMAND_VENUSMNGR_PRIVILEGED_GET_STATUS			0x0213
#define SOLAREDGE_COMMAND_VENUSMNGR_CURRENT_MODEM_START				0x0214
#define SOLAREDGE_COMMAND_VENUSMNGR_CURRENT_MODEM_SEND				0x0215
#define SOLAREDGE_COMMAND_VENUSMNGR_CURRENT_MODEM_SEND_PAIRING			0x0216
#define SOLAREDGE_COMMAND_VENUSMNGR_CURRENT_MODEM_GET_STATUS			0x0217
#define SOLAREDGE_COMMAND_VENUSMNGR_KA_DATA_SEND				0x0218
#define SOLAREDGE_COMMAND_VENUSMNGR_CURRENT_MODEM_END_PAIRING			0x0219
#define SOLAREDGE_COMMAND_VENUSMNGR_FORCE_GRID_MON				0x021a
#define SOLAREDGE_COMMAND_VENUSMNGR_FORCE_SKIP_GRID_MON				0x021b
#define SOLAREDGE_COMMAND_VENUSMNGR_START_SUPERVISE				0x021c
#define SOLAREDGE_COMMAND_VENUSMNGR_READ_A2D_MEAS				0x021d
#define SOLAREDGE_COMMAND_VENUSMNGR_GET_COUNTRY_DEFAULTS			0x021e
#define SOLAREDGE_COMMAND_VENUSMNGR_SET_PRODUCT_MODEL				0x021f
#define SOLAREDGE_COMMAND_VENUSMNGR_GET_PRODUCT_MODEL				0x0220
#define SOLAREDGE_COMMAND_VENUSMNGR_SET_DYNAMIC_INVPWR_PARAM			0x0221
#define SOLAREDGE_COMMAND_INVERTER_ENTER_BURN_INVPWR_MODE			0x0222
#define SOLAREDGE_COMMAND_VENUSMNGR_MPPT_TRAVEL					0x0223
#define SOLAREDGE_COMMAND_VENUSMNGR_SET_PWR_PARAM				0x0224
#define SOLAREDGE_COMMAND_INVERTER_CURRENT_MODEM_SET_DATA_BIT			0x0225
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_READ_ISE_MEAS1				0x0280
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_READ_ISE_MEAS2				0x0281
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_READ_SE_MEAS				0x0282
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_GET_SYS_STATUS				0x0283
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_GET_TELEM				0x0284
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_RX_TEST				0x0285
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_GET_COUNTRY_CODE			0x0286
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_PRIVILEGED_GET_EVENT			0x0287
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_PRIVILEGED_GET_STATUS			0x0288
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_CURRENT_MODEM_GET_STATUS		0x0289
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_READ_A2D_MEAS				0x028a
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_GET_COUNTRY_DEFAULTS			0x028b
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_GET_PRODUCT_MODEL			0x028c
#define SOLAREDGE_COMMAND_RESP_VENUSMNGR_SET_DYNAMIC_ISE_PARAM			0x028d
#define SOLAREDGE_COMMAND_POLESTAR_TELEMS_START					0x0300
#define SOLAREDGE_COMMAND_POLESTAR_TELEMS_STOP					0x0301
#define SOLAREDGE_COMMAND_POLESTAR_MASTER_GRANT					0x0302
#define SOLAREDGE_COMMAND_POLESTAR_RTC_SET					0x0303
#define SOLAREDGE_COMMAND_POLESTAR_TEST_RAM					0x0304
#define SOLAREDGE_COMMAND_POLESTAR_TEST_FLASH					0x0305
#define SOLAREDGE_COMMAND_POLESTAR_MAC_ADDR_GET					0x0306
#define SOLAREDGE_COMMAND_POLESTAR_IP_ADDR_GET					0x0307
#define SOLAREDGE_COMMAND_POLESTAR_SLAVE_ID_DETECT_INIT				0x0308
#define SOLAREDGE_COMMAND_POLESTAR_SLAVE_ID_DETECT_GET_ID			0x0309
#define SOLAREDGE_COMMAND_POLESTAR_SLAVE_ID_DETECT_STOP				0x030a
#define SOLAREDGE_COMMAND_POLESTAR_UART_ZB_BRIDGE				0x030b
#define SOLAREDGE_COMMAND_POLESTAR_SEND_PING					0x030c
#define SOLAREDGE_COMMAND_POLESTAR_LCD_TEST_MODE				0x030d
#define SOLAREDGE_COMMAND_POLESTAR_CONFTOOL_START				0x030e
#define SOLAREDGE_COMMAND_POLESTAR_ETHERNET_STAT				0x030f
#define SOLAREDGE_COMMAND_POLESTAR_GET_FIFO_FLASH_INFO				0x0310
#define SOLAREDGE_COMMAND_POLESTAR_RESET_FIFO_FLASH				0x0311
#define SOLAREDGE_COMMAND_POLESTAR_RESET_FLASH					0x0312
#define SOLAREDGE_COMMAND_POLESTAR_RS485_MSTR_SLV_DET_START			0x0313
#define SOLAREDGE_COMMAND_POLESTAR_RS485_MSTR_SLV_DET_STATUS			0x0314
#define SOLAREDGE_COMMAND_POLESTAR_UART_ZB_SET					0x0315
#define SOLAREDGE_COMMAND_POLESTAR_TCP_TEST					0x0316
#define SOLAREDGE_COMMAND_POLESTAR_TIMER_ADVANCE				0x0317
#define SOLAREDGE_COMMAND_POLESTAR_ERASE_FLASH_FIFO_FAST			0x0318
#define SOLAREDGE_COMMAND_POLESTAR_SELF_KA					0x0319
#define SOLAREDGE_COMMAND_POLESTAR_ISE_BRIDGE					0x031a
#define SOLAREDGE_COMMAND_POLESTAR_ERASE_STATISTICS				0x031b
#define SOLAREDGE_COMMAND_POLESTAR_GET_POK_STATUS				0x031c
#define SOLAREDGE_COMMAND_POLESTAR_INVERTER_HW_RESET				0x031d
#define SOLAREDGE_COMMAND_POLESTAR_ZB_PRESENT_STATUS				0x031e
#define SOLAREDGE_COMMAND_POLESTAR_GET_ALL_SUPPORTED_LANGUAGES_INDEXES		0x031f
#define SOLAREDGE_COMMAND_POLESTAR_GET_ALL_SUPPORTED_GSM_MODEMS_INDEXES		0x0320
#define SOLAREDGE_COMMAND_POLESTAR_GET_S_OK_STATUS				0x0321
#define SOLAREDGE_COMMAND_POLESTAR_GET_ENERGY_STATISTICS_STATUS			0x0322
#define SOLAREDGE_COMMAND_POLESTAR_GET_GSM_PRESENT_STATUS			0x0323
#define SOLAREDGE_COMMAND_POLESTAR_SET_STATISTICS_ELEMENT			0x0324
#define SOLAREDGE_COMMAND_POLESTAR_GEMINI_RS485_MSTR_SLV_DET_START		0x0325
#define SOLAREDGE_COMMAND_POLESTAR_GEMINI_RS485_MSTR_SLV_DET_STATUS		0x0326
#define SOLAREDGE_COMMAND_POLESTAR_GET_GEMINI_GFD_STATUS			0x0327
#define SOLAREDGE_COMMAND_POLESTAR_GET_ERROR_LOG				0x0328
#define SOLAREDGE_COMMAND_POLESTAR_BLOCK_SERVER_CONTROL				0x0329
#define SOLAREDGE_COMMAND_POLESTAR_GET_SERVER_CONTROL_STATUS			0x032a
#define SOLAREDGE_COMMAND_POLESTAR_TEST_SD_FLASH				0x032b
#define SOLAREDGE_COMMAND_POLESTAR_GET_WARNING_LOG				0x032c
#define SOLAREDGE_COMMAND_POLESTAR_RESET_MODBUS_DEVICE_DATA			0x032d
#define SOLAREDGE_COMMAND_POLESTAR_TURN_OFF_INTERNAL_SRAM_BATTERY_BACKUP	0x032e
#define SOLAREDGE_COMMAND_POLESTAR_WRITE_LCD					0x032f
#define SOLAREDGE_COMMAND_POLESTAR_READ_LAST_BUTTONS				0x0330
#define SOLAREDGE_COMMAND_POLESTAR_GET_STATISTICS_ELEMENT			0x0331
#define SOLAREDGE_COMMAND_POLESTAR_SEND_POWER_REDUCER_SLAVE_PACKET		0x0332
#define SOLAREDGE_COMMAND_POLESTAR_SEND_POWER_REDUCER_MASTER_PACKET		0x0333
#define SOLAREDGE_COMMAND_POLESTAR_GET_WIFI_PRESENT_STATUS			0x0334
#define SOLAREDGE_COMMAND_POLESTAR_GET_PORT_EXPANDER_GPIO_DATA			0x0335
#define SOLAREDGE_COMMAND_POLESTAR_SET_PORT_EXPANDER_GPIO_DATA			0x0336
#define SOLAREDGE_COMMAND_POLESTAR_READ_LCD					0x0337
#define SOLAREDGE_COMMAND_POLESTAR_SIMULATE_BUTTON_PRESSING			0x0338
#define SOLAREDGE_COMMAND_POLESTAR_INV_ACTIVATE					0x0339
#define SOLAREDGE_COMMAND_POLESTAR_MODBUS_SLAVE_PACKET				0x033a
#define SOLAREDGE_COMMAND_POLESTAR_GET_BUTTON_STATE				0x033b
#define SOLAREDGE_COMMAND_POLESTAR_GET_A2D_VALS					0x033c
#define SOLAREDGE_COMMAND_POLESTAR_GET_OPMODE					0x033d
#define SOLAREDGE_COMMAND_POLESTAR_SET_BACKLIGHT				0x033e
#define SOLAREDGE_COMMAND_POLESTAR_READ_FIFO_PAGE				0x033f
#define SOLAREDGE_COMMAND_POLESTAR_GET_CURRENT_SCREEN_INDEX			0x0340
#define SOLAREDGE_COMMAND_POLESTAR_GET_IDENTITY					0x0341
#define SOLAREDGE_COMMAND_POLESTAR_GET_SUPPORTED_COMMANDS			0x0342
#define SOLAREDGE_COMMAND_POLESTAR_PAIRING_START				0x0343
#define SOLAREDGE_COMMAND_POLESTAR_PAIRING_STATUS				0x0344
#define SOLAREDGE_COMMAND_POLESTAR_PRODUCT_RESET				0x0345
#define SOLAREDGE_COMMAND_POLESTAR_PLC_CMD_EXECUTE				0x0346
#define SOLAREDGE_COMMAND_POLESTAR_GET_STATUS					0x0347
#define SOLAREDGE_COMMAND_POLESTAR_FIRE_SAFETY_LOCK_MASTER			0x0348
#define SOLAREDGE_COMMAND_POLESTAR_FIRE_SAFETY_LOCK_SLAVE			0x0349
#define SOLAREDGE_COMMAND_POLESTAR_FIRE_SAFETY_REPORT				0x034a
#define SOLAREDGE_COMMAND_POLESTAR_UART_BRIDGE_INIT				0x034b
#define SOLAREDGE_COMMAND_POLESTAR_SEND_UART_DATA				0x034c
#define SOLAREDGE_COMMAND_POLESTAR_LED_TEST					0x034d
#define SOLAREDGE_COMMAND_POLESTAR_SEND_FAKE_TELEMS				0x034e
#define SOLAREDGE_COMMAND_RESP_POLESTAR_RTC_SET					0x0380
#define SOLAREDGE_COMMAND_RESP_POLESTAR_MAC_ADDR_GET				0x0381
#define SOLAREDGE_COMMAND_RESP_POLESTAR_IP_ADDR_GET				0x0382
#define SOLAREDGE_COMMAND_RESP_POLESTAR_SEND_PING				0x0383
#define SOLAREDGE_COMMAND_RESP_POLESTAR_ETHERNET_STAT				0x0384
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_FIFO_FLASH_INFO			0x0385
#define SOLAREDGE_COMMAND_RESP_POLESTAR_RS485_MSTR_SLV_DET_STATUS		0x0386
#define SOLAREDGE_COMMAND_RESP_POLESTAR_TCP_TEST_RESP				0x0387
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_POK_STATUS				0x0388
#define SOLAREDGE_COMMAND_RESP_POLESTAR_INVERTER_HW_RESET			0x0389
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_ALL_SUPPORTED_LANGUAGES_INDEXES	0x038a
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_ALL_SUPPORTED_GSM_MODEMS_INDEXES	0x038b
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_S_OK_STATUS				0x038c
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_ENERGY_STATISTICS_STATUS		0x038d
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_GSM_PRESENT_STATUS			0x038e
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GEMINI_RS485_MSTR_SLV_DET_STATUS	0x038f
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_GEMINI_GFD_STATUS			0x0390
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_ERROR_LOG				0x0391
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_SERVER_CONTROL_STATUS		0x0392
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_WARNING_LOG				0x0393
#define SOLAREDGE_COMMAND_RESP_POLESTAR_READ_LAST_BUTTONS			0x0394
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_STATISTICS_ELEMENT			0x0395
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_WIFI_PRESENT_STATUS			0x0396
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_PORT_EXPANDER_GPIO_DATA		0x0397
#define SOLAREDGE_COMMAND_RESP_POLESTAR_READ_LCD				0x0398
#define SOLAREDGE_COMMAND_RESP_POLESTAR_MODBUS_SLAVE_PACKET			0x0399
#define SOLAREDGE_COMMAND_RESP_POLESTAR_MASTER_GRANT_ACK			0x039a
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_IDENTITY				0x039b
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_SUPPORTED_COMMANDS			0x039c
#define SOLAREDGE_COMMAND_RESP_POLESTAR_PAIRING_START				0x039d
#define SOLAREDGE_COMMAND_RESP_POLESTAR_PAIRING_STATUS				0x039e
#define SOLAREDGE_COMMAND_RESP_POLESTAR_GET_STATUS				0x039f
#define SOLAREDGE_COMMAND_RESP_POLESTAR_FIRE_SAFETY_REPORT			0x03a0
#define SOLAREDGE_COMMAND_RESP_POLESTAR_SEND_UART_DATA				0x03a1
#define SOLAREDGE_COMMAND_SUNTRACER_READ_FLASH					0x0400
#define SOLAREDGE_COMMAND_SUNTRACER_START					0x0401
#define SOLAREDGE_COMMAND_SUNTRACER_SET_RTC					0x0402
#define SOLAREDGE_COMMAND_SUNTRACER_DEL_FLASH					0x0403
#define SOLAREDGE_COMMAND_SUNTRACER_DEL_FLASH_SECTOR				0x0404
#define SOLAREDGE_COMMAND_RESP_SUNTRACER_TRACE					0x0480
#define SOLAREDGE_COMMAND_RESP_SUNTRACER_FLASH					0x0481
#define SOLAREDGE_COMMAND_SERVER_POST_DATA					0x0500
#define SOLAREDGE_COMMAND_SERVER_GET_GMT					0x0501
#define SOLAREDGE_COMMAND_SERVER_GET_NAME					0x0502
#define SOLAREDGE_COMMAND_SERVER_SET_KEY					0x0503
#define SOLAREDGE_COMMAND_RESP_SERVER_GMT					0x0580
#define SOLAREDGE_COMMAND_RESP_SERVER_NAME					0x0581
#define SOLAREDGE_COMMAND_RESP_CONFTOOL_PLC_DATA				0x0680
#define SOLAREDGE_COMMAND_JUPMNGR_READ_JUPPWR_MEAS1				0x0800
#define SOLAREDGE_COMMAND_JUPMNGR_READ_JUPPWR_MEAS2				0x0801
#define SOLAREDGE_COMMAND_JUPMNGR_READ_JUPPWR_MEAS3				0x0802
#define SOLAREDGE_COMMAND_JUPMNGR_READ_JUPPWR_MEAS4				0x0803
#define SOLAREDGE_COMMAND_JUPMNGR_READ_JUPPWR_MEAS5				0x0804
#define SOLAREDGE_COMMAND_JUPMNGR_READ_MEAS					0x0805
#define SOLAREDGE_COMMAND_JUPMNGR_GET_SYS_STATUS				0x0806
#define SOLAREDGE_COMMAND_JUPMNGR_GET_TELEM					0x0807
#define SOLAREDGE_COMMAND_JUPMNGR_GET_COUNTRY_CODE				0x0808
#define SOLAREDGE_COMMAND_JUPMNGR_SET_COUNTRY					0x0809
#define SOLAREDGE_COMMAND_JUPMNGR_GET_COUNTRY_DEFAULTS				0x080a
#define SOLAREDGE_COMMAND_JUPMNGR_PRIVILEGED_MODE				0x080b
#define SOLAREDGE_COMMAND_JUPMNGR_PRIVILEGED_SET_PARAM				0x080c
#define SOLAREDGE_COMMAND_JUPMNGR_PRIVILEGED_GET_EVENT				0x080d
#define SOLAREDGE_COMMAND_JUPMNGR_PRIVILEGED_GET_STATUS				0x080e
#define SOLAREDGE_COMMAND_JUPMNGR_SET_PRODUCT_MODEL				0x080f
#define SOLAREDGE_COMMAND_JUPMNGR_GET_PRODUCT_MODEL				0x0810
#define SOLAREDGE_COMMAND_JUPMNGR_DYNAMIC_SET_INVPWR_PARAM			0x0811
#define SOLAREDGE_COMMAND_JUPMNGR_GET_INVPWR_PARAM_TYPE				0x0812
#define SOLAREDGE_COMMAND_JUPMNGR_GET_FANS_STATUS				0x0813
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_READ_JUPPWR_MEAS1			0x0880
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_READ_JUPPWR_MEAS2			0x0881
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_READ_JUPPWR_MEAS3			0x0882
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_READ_JUPPWR_MEAS4			0x0883
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_READ_JUPPWR_MEAS5			0x0884
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_READ_MEAS				0x0885
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_SYS_STATUS				0x0886
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_TELEM				0x0887
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_COUNTRY_CODE				0x0888
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_COUNTRY_DEFAULTS			0x0889
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_PRIVILEGED_GET_EVENT			0x088a
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_PRIVILEGED_GET_STATUS			0x088b
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_PRODUCT_MODEL			0x088c
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_INVPWR_PARAM_TYPE			0x088d
#define SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_FANS_STATUS				0x088e
#define SOLAREDGE_COMMAND_INVERTER_TURN_15V_ON					0x0900
#define SOLAREDGE_COMMAND_INVERTER_TURN_15V_OFF					0x0901
#define SOLAREDGE_COMMAND_INVERTER_ENABLE_RELAYS				0x0902
#define SOLAREDGE_COMMAND_INVERTER_DISABLE_RELAYS				0x0903
#define SOLAREDGE_COMMAND_INVERTER_DYNAMIC_POWER_LIMIT				0x0904
#define SOLAREDGE_COMMAND_INVERTER_IVTRACE_START				0x0905
#define SOLAREDGE_COMMAND_INVERTER_GRID_TRIP_TEST				0x0906
#define SOLAREDGE_COMMAND_INVERTER_SET_LMVGC_PARAMS1				0x0907
#define SOLAREDGE_COMMAND_INVERTER_GET_LMVGC_PARAMS1				0x0908
#define SOLAREDGE_COMMAND_INVERTER_SET_PWR_GAIN_PARAMS				0x0909
#define SOLAREDGE_COMMAND_INVERTER_SET_LMVGC_PARAMS2				0x090a
#define SOLAREDGE_COMMAND_INVERTER_GET_LMVGC_PARAMS2				0x090b
#define SOLAREDGE_COMMAND_INVERTER_SET_LMVGC_PARAMS3				0x090c
#define SOLAREDGE_COMMAND_INVERTER_GET_LMVGC_PARAMS3				0x090d
#define SOLAREDGE_COMMAND_INVERTER_LOCK_IN					0x090e
#define SOLAREDGE_COMMAND_INVERTER_LOCK_OUT					0x090f
#define SOLAREDGE_COMMAND_INVERTER_GET_VDC					0x0910
#define SOLAREDGE_COMMAND_INVERTER_PAIRING_DO_NOTHING				0x0911
#define SOLAREDGE_COMMAND_INVERTER_PAIRING_DO_SAFETY				0x0912
#define SOLAREDGE_COMMAND_RESP_INVERTER_DYNAMIC_POWER_LIMIT			0x0980
#define SOLAREDGE_COMMAND_RESP_INVERTER_GET_LMVGC_PARAMS			0x0981
#define SOLAREDGE_COMMAND_VEGA_READ_MEAS					0x0a00
#define SOLAREDGE_COMMAND_VEGA_GET_SYS_STATUS					0x0a01
#define SOLAREDGE_COMMAND_VEGA_GET_TELEM					0x0a02
#define SOLAREDGE_COMMAND_VEGA_GET_MAX_VDC_VALUE				0x0a03
#define SOLAREDGE_COMMAND_VEGA_SET_MAX_VDC_VALUE				0x0a04
#define SOLAREDGE_COMMAND_VEGA_RELAY_SET					0x0a05
#define SOLAREDGE_COMMAND_VEGA_SET_OPMODE					0x0a06
#define SOLAREDGE_COMMAND_VEGA_GET_OPMODE					0x0a07
#define SOLAREDGE_COMMAND_VEGA_SET_RANGE					0x0a08
#define SOLAREDGE_COMMAND_RESP_VEGA_READ_MEAS					0x0a80
#define SOLAREDGE_COMMAND_RESP_VEGA_GET_SYS_STATUS				0x0a81
#define SOLAREDGE_COMMAND_RESP_VEGA_GET_TELEM					0x0a82
#define SOLAREDGE_COMMAND_RESP_VEGA_GET_MAX_VDC_VALUE				0x0a83
#define SOLAREDGE_COMMAND_COMBI_PAUSE_MONITORING				0x0b00
#define SOLAREDGE_COMMAND_COMBI_SET_TIME_STAMP					0x0b01
#define SOLAREDGE_COMMAND_COMBI_RCD_CALIBRATION					0x0b02
#define SOLAREDGE_COMMAND_COMBI_GET_TELEM					0x0b03
#define SOLAREDGE_COMMAND_COMBI_FORCE_TELEM					0x0b04
#define SOLAREDGE_COMMAND_COMBI_SWITCHES_CONNECT				0x0b05
#define SOLAREDGE_COMMAND_COMBI_SWITCHES_DISCONNECT				0x0b06
#define SOLAREDGE_COMMAND_COMBI_SWITCHES_CONNECT_ALL				0x0b07
#define SOLAREDGE_COMMAND_COMBI_SWITCHES_DISCONNECT_ALL				0x0b08
#define SOLAREDGE_COMMAND_COMBI_RCD_TEST_EXECUTE				0x0b09
#define SOLAREDGE_COMMAND_COMBI_RELAYS_TEST_EXECUTE				0x0b0a
#define SOLAREDGE_COMMAND_COMBI_GET_COMBISTRING_PARAM				0x0b0b
#define SOLAREDGE_COMMAND_COMBI_SET_COMBISTRING_PARAM				0x0b0c
#define SOLAREDGE_COMMAND_COMBI_GET_ALL_COMBISTRING_PARAMS			0x0b0d
#define SOLAREDGE_COMMAND_COMBI_GET_ALL_COMBI_PARAMS				0x0b0e
#define SOLAREDGE_COMMAND_COMBI_READ_MEASUREMENTS				0x0b0f
#define SOLAREDGE_COMMAND_COMBI_GET_STRING_STATUS				0x0b10
#define SOLAREDGE_COMMAND_COMBI_GET_COMBI_STATUS				0x0b11
#define SOLAREDGE_COMMAND_COMBI_GET_ACTIVE_STRINGS				0x0b12
#define SOLAREDGE_COMMAND_COMBI_FWD_STRING_TELEM				0x0b13
#define SOLAREDGE_COMMAND_COMBI_FWD_COMBI_TELEM					0x0b14
#define SOLAREDGE_COMMAND_COMBI_GET_UNIFIED_STRING_STATUS			0x0b15
#define SOLAREDGE_COMMAND_COMBI_GET_UNIFIED_COMBI_STATUS			0x0b16
#define SOLAREDGE_COMMAND_COMBI_CHECK_INNER_PROTOCOL				0x0b17
#define SOLAREDGE_COMMAND_COMBI_SWITCHES_CONNECT_RELAY				0x0b18
#define SOLAREDGE_COMMAND_COMBI_SWITCHES_DISCONNECT_RELAY			0x0b19
#define SOLAREDGE_COMMAND_COMBI_GET_GEMINI_STRING_IDS				0x0b1a
#define SOLAREDGE_COMMAND_COMBI_GET_ALL_SWITCHES_STATUS				0x0b1b
#define SOLAREDGE_COMMAND_COMBI_SET_RCD_TEST_PIN				0x0b1c
#define SOLAREDGE_COMMAND_COMBI_RELAYS_TEST_CHECK_CONDS				0x0b1d
#define SOLAREDGE_COMMAND_RESP_COMBI_GET_TELEM					0x0b80
#define SOLAREDGE_COMMAND_RESP_COMBI_GET_STRING_STATUS				0x0b81
#define SOLAREDGE_COMMAND_RESP_COMBI_GET_COMBI_STATUS				0x0b82
#define SOLAREDGE_COMMAND_RESP_COMBI_GET_ACTIVE_STRINGS				0x0b83
#define SOLAREDGE_COMMAND_RESP_COMBI_GET_UNIFIED_STRING_STATUS			0x0b84
#define SOLAREDGE_COMMAND_RESP_COMBI_GET_UNIFIED_COMBI_STATUS			0x0b85
#define SOLAREDGE_COMMAND_RESP_COMBI_GET_GEMINI_STRING_IDS			0x0b86
#define SOLAREDGE_COMMAND_INVPWR_GET_ERROR_STATUS				0x0c00
#define SOLAREDGE_COMMAND_INVPWR_GET_STATUS					0x0c01
#define SOLAREDGE_COMMAND_INVPWR_GO						0x0c02
#define SOLAREDGE_COMMAND_INVPWR_HALT						0x0c03
#define SOLAREDGE_COMMAND_INVPWR_CONST_DUTY_CYCLE				0x0c04
#define SOLAREDGE_COMMAND_INVPWR_DUMY_ERROR					0x0c05
#define SOLAREDGE_COMMAND_INVPWR_PAIRING_SET_STATE				0x0c06
#define SOLAREDGE_COMMAND_INVPWR_TEST_IAC_CONTROL				0x0c07
#define SOLAREDGE_COMMAND_RESP_INVPWR_GET_ERROR_STATUS				0x0c80
#define SOLAREDGE_COMMAND_RESP_INVPWR_GET_STATUS				0x0c81
#define SOLAREDGE_COMMAND_RESP_INVPWR_GO					0x0c82
#define SOLAREDGE_COMMAND_RESP_INVPWR_HALT					0x0c83
#define SOLAREDGE_COMMAND_RESP_INVPWR_CONST_DUTY_CYCLE				0x0c84
#define SOLAREDGE_COMMAND_RESP_INVPWR_DUMY_ERROR				0x0c85
#define SOLAREDGE_COMMAND_BOOTLOADER_SECURE					0x1400
#define SOLAREDGE_COMMAND_BOOTLOADER_UNSECURE					0x1401
#define SOLAREDGE_COMMAND_ACTIVATOR_ACTIVATE					0x1500
#define SOLAREDGE_COMMAND_ACTIVATOR_GET_ADC_SAMPLES				0x1501
#define SOLAREDGE_COMMAND_ACTIVATOR_SET_VO_RANGE				0x1502
#define SOLAREDGE_COMMAND_ACTIVATOR_GET_AVG_SAMPLES				0x1503
#define SOLAREDGE_COMMAND_ACTIVATOR_TX_TEST					0x1504
#define SOLAREDGE_COMMAND_ACTIVATOR_LCD_TEST					0x1505
#define SOLAREDGE_COMMAND_ACTIVATOR_BUTTONS_TEST				0x1506
#define SOLAREDGE_COMMAND_FANCONTROL_SET_PWM					0x1600
#define SOLAREDGE_COMMAND_FANCONTROL_GET_PWM					0x1601
#define SOLAREDGE_COMMAND_FANCONTROL_GET_ALL_PWM				0x1602
#define SOLAREDGE_COMMAND_FANCONTROL_SHUT_ALL_PWM				0x1603
#define SOLAREDGE_COMMAND_FANCONTROL_RES					0x1680
#define SOLAREDGE_COMMAND_DISPLAY_BOARD_LCD_WRITE				0x1700
#define SOLAREDGE_COMMAND_DISPLAY_BOARD_LED_SET 				0x1701

#define SOLAREDGE_DEVICETYPE_OPTIMIZER		0x0000
#define SOLAREDGE_DEVICETYPE_INVERTER_1PHASE	0x0010
#define SOLAREDGE_DEVICETYPE_INVERTER_3PHASE	0x0011
#define SOLAREDGE_DEVICETYPE_OPTIMIZER2		0x0080
#define SOLAREDGE_DEVICETYPE_EVENT		0x0300

typedef struct solaredge_packet_header {
	uint16_t length;
	uint16_t length_inverse;
	uint16_t sequence_number;
	uint32_t source_address;
	uint32_t destination_address;
	uint16_t command_type;
} t_solaredge_packet_header;

typedef struct solaredge_device_header {
	uint16_t type;
	uint32_t id;
	uint16_t device_length;
} t_solaredge_device_header;

typedef struct solaredge_conversion_data {
	bool session_key_found;
	gcry_cipher_hd_t cipher_hd_session;
	uint16_t expected_sequence_number;
} t_solaredge_conversion_data;

void proto_reg_handoff_solaredge(void);
void proto_register_solaredge(void);

static dissector_handle_t solaredge_handle;

static bool global_show_unknown_fields = true;

static expert_field ei_solaredge_invalid_length;
static expert_field ei_solaredge_invalid_crc;

static int proto_solaredge;

static int hf_solaredge_length_type;
static int hf_solaredge_length_inverse_type;
static int hf_solaredge_sequence_number_type;
static int hf_solaredge_source_address_type;
static int hf_solaredge_destination_address_type;
static int hf_solaredge_command_type;
static int hf_solaredge_crc_type;
static int hf_solaredge_crc_status_type;

static int hf_solaredge_payload_type;

static int hf_solaredge_session_key_type;

static int hf_solaredge_post_type;
static int hf_solaredge_post_device_type;
static int hf_solaredge_post_device_type_type;
static int hf_solaredge_post_device_id_type;
static int hf_solaredge_post_length_type;

static int hf_solaredge_post_padding_uint32_type;
static int hf_solaredge_post_padding_float_type;

static int hf_solaredge_post_singlephase_inverter_timestamp_type;
static int hf_solaredge_post_singlephase_inverter_uptime_type;
static int hf_solaredge_post_singlephase_inverter_interval_type;
static int hf_solaredge_post_singlephase_inverter_temperature_type;
static int hf_solaredge_post_singlephase_inverter_energy_day_type;
static int hf_solaredge_post_singlephase_inverter_energy_interval_type;
static int hf_solaredge_post_singlephase_inverter_ac_voltage_type;
static int hf_solaredge_post_singlephase_inverter_ac_current_type;
static int hf_solaredge_post_singlephase_inverter_ac_frequency_type;
static int hf_solaredge_post_singlephase_inverter_dc_voltage_type;
static int hf_solaredge_post_singlephase_inverter_energy_total_type;
static int hf_solaredge_post_singlephase_inverter_power_max_type;
static int hf_solaredge_post_singlephase_inverter_ac_power_type;

static int hf_solaredge_post_optimizer_inverter_type;
static int hf_solaredge_post_optimizer_uptime_type;
static int hf_solaredge_post_optimizer_dc_current_panel_type;
static int hf_solaredge_post_optimizer_timestamp_type;
static int hf_solaredge_post_optimizer_uptime_short_type;
static int hf_solaredge_post_optimizer_dc_voltage_panel_type;
static int hf_solaredge_post_optimizer_dc_voltage_optimzer_type;
static int hf_solaredge_post_optimizer_dc_current_optimzer_type;
static int hf_solaredge_post_optimizer_energy_day_type;
static int hf_solaredge_post_optimizer_temperature_type;

static int hf_solaredge_post_event_timestamp_type;
static int hf_solaredge_post_event_type_type;
static int hf_solaredge_post_event_event_start_timestamp_type;
static int hf_solaredge_post_event_event_timezone_offset_type;
static int hf_solaredge_post_event_event_end_timestamp_type;

static int ett_solaredge_packet;
static int ett_solaredge_packet_decrypted;
static int ett_solaredge_packet_post;
static int ett_solaredge_packet_post_device;

static const value_string solaredge_packet_commandtypes[] = {
	{ SOLAREDGE_COMMAND_PARAMS_RESET,					"PARAMS_RESET" },
	{ SOLAREDGE_COMMAND_PARAMS_SET_SINGLE,					"PARAMS_SET_SINGLE" },
	{ SOLAREDGE_COMMAND_PARAMS_GET_SINGLE,					"PARAMS_GET_SINGLE" },
	{ SOLAREDGE_COMMAND_PARAMS_GET_INFO,					"PARAMS_GET_INFO" },
	{ SOLAREDGE_COMMAND_PARAMS_GET_NAME,					"PARAMS_GET_NAME" },
	{ SOLAREDGE_COMMAND_PARAMS_GET_NUM,					"PARAMS_GET_NUM" },
	{ SOLAREDGE_COMMAND_PARAMS_GET_ALL,					"PARAMS_GET_ALL" },
	{ SOLAREDGE_COMMAND_PARAMS_SET_ALL,					"PARAMS_SET_ALL" },
	{ SOLAREDGE_COMMAND_PARAMS_SET_SINGLE_NOSAVE,				"PARAMS_SET_SINGLE_NOSAVE" },
	{ SOLAREDGE_COMMAND_PARAMS_SAVE,					"PARAMS_SAVE" },
	{ SOLAREDGE_COMMAND_PARAMS_POLICY_ENABLE,				"PARAMS_POLICY_ENABLE" },
	{ SOLAREDGE_COMMAND_PARAMS_POLICY_DISABLE,				"PARAMS_POLICY_DISABLE" },
	{ SOLAREDGE_COMMAND_PARAMS_POLICY_DISABLE_VOLATILE,			"PARAMS_POLICY_DISABLE_VOLATILE" },
	{ SOLAREDGE_COMMAND_PARAMS_SET_POLICY_PASSWORD,				"PARAMS_SET_POLICY_PASSWORD" },
	{ SOLAREDGE_COMMAND_PARAMS_GET_VOLATILE,				"PARAMS_GET_VOLATILE" },
	{ SOLAREDGE_COMMAND_PARAMS_SET_VOLATILE,				"PARAMS_SET_VOLATILE" },
	{ SOLAREDGE_COMMAND_UPGRADE_START,					"UPGRADE_START" },
	{ SOLAREDGE_COMMAND_UPGRADE_WRITE,					"UPGRADE_WRITE" },
	{ SOLAREDGE_COMMAND_UPGRADE_FINISH,					"UPGRADE_FINISH" },
	{ SOLAREDGE_COMMAND_UPGRADE_READ_DATA,					"UPGRADE_READ_DATA" },
	{ SOLAREDGE_COMMAND_UPGRADE_READ_SIZE,					"UPGRADE_READ_SIZE" },
	{ SOLAREDGE_COMMAND_MISC_RESET,						"MISC_RESET" },
	{ SOLAREDGE_COMMAND_MISC_STOP,						"MISC_STOP" },
	{ SOLAREDGE_COMMAND_MISC_DUMMY,						"MISC_DUMMY" },
	{ SOLAREDGE_COMMAND_MISC_GET_VER,					"MISC_GET_VER" },
	{ SOLAREDGE_COMMAND_MISC_GET_TYPE,					"MISC_GET_TYPE" },
	{ SOLAREDGE_COMMAND_MISC_PAYLOAD,					"MISC_PAYLOAD" },
	{ SOLAREDGE_COMMAND_MISC_SET_ID,					"MISC_SET_ID" },
	{ SOLAREDGE_COMMAND_MISC_READ_MEMORY,					"MISC_READ_MEMORY" },
	{ SOLAREDGE_COMMAND_MISC_PARAMS_PARTIAL_RESET,				"MISC_PARAMS_PARTIAL_RESET" },
	{ SOLAREDGE_COMMAND_MISC_GET_MAX_PACKET_SIZE,				"MISC_GET_MAX_PACKET_SIZE" },
	{ SOLAREDGE_COMMAND_MISC_ENCRYPTED,					"MISC_ENCRYPTED" },
	{ SOLAREDGE_COMMAND_PARAMS_SMART_LOAD_PARAMS,				"PARAMS_SMART_LOAD_PARAMS" },
	{ SOLAREDGE_COMMAND_MISC_PARAMS_PARTIAL_RESET2,				"MISC_PARAMS_PARTIAL_RESET2" },
	{ SOLAREDGE_COMMAND_PARAMS_IGNORE_PARAMS_LIST,				"PARAMS_IGNORE_PARAMS_LIST" },
	{ SOLAREDGE_COMMAND_PARAMS_PARTIAL_RESET_AS_LEVEL,			"PARAMS_PARTIAL_RESET_AS_LEVEL" },
	{ SOLAREDGE_COMMAND_PARAMS_PARTIAL_RESET_PCB_LEVEL,			"PARAMS_PARTIAL_RESET_PCB_LEVEL" },
	{ SOLAREDGE_COMMAND_RESP_ACK,						"RESP_ACK" },
	{ SOLAREDGE_COMMAND_RESP_NACK,						"RESP_NACK" },
	{ SOLAREDGE_COMMAND_RESP_PARAMS_SINGLE,					"RESP_PARAMS_SINGLE" },
	{ SOLAREDGE_COMMAND_RESP_PARAMS_INFO,					"RESP_PARAMS_INFO" },
	{ SOLAREDGE_COMMAND_RESP_PARAMS_NAME,					"RESP_PARAMS_NAME" },
	{ SOLAREDGE_COMMAND_RESP_PARAMS_NUM,					"RESP_PARAMS_NUM" },
	{ SOLAREDGE_COMMAND_RESP_PARAMS_ALL,					"RESP_PARAMS_ALL" },
	{ SOLAREDGE_COMMAND_RESP_PARAMS_INCORRECT_PASSWORD,			"RESP_PARAMS_INCORRECT_PASSWORD" },
	{ SOLAREDGE_COMMAND_RESP_UPGRADE_DATA,					"RESP_UPGRADE_DATA" },
	{ SOLAREDGE_COMMAND_RESP_UPGRADE_SIZE,					"RESP_UPGRADE_SIZE" },
	{ SOLAREDGE_COMMAND_RESP_MISC_GET_VER,					"RESP_MISC_GET_VER" },
	{ SOLAREDGE_COMMAND_RESP_MISC_GET_TYPE,					"RESP_MISC_GET_TYPE" },
	{ SOLAREDGE_COMMAND_RESP_MISC_PAYLOAD,					"RESP_MISC_PAYLOAD" },
	{ SOLAREDGE_COMMAND_RESP_MISC_READ_MEMORY,				"RESP_MISC_READ_MEMORY" },
	{ SOLAREDGE_COMMAND_RESP_MISC_GET_MAX_PACKET_SIZE,			"RESP_MISC_GET_MAX_PACKET_SIZE" },
	{ SOLAREDGE_COMMAND_MERCURY_PWM_SET,					"MERCURY_PWM_SET" },
	{ SOLAREDGE_COMMAND_MERCURY_PWM_ENABLE,					"MERCURY_PWM_ENABLE" },
	{ SOLAREDGE_COMMAND_MERCURY_A2D_SAMPLE,					"MERCURY_A2D_SAMPLE" },
	{ SOLAREDGE_COMMAND_MERCURY_KA,						"MERCURY_KA" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_VIREF,					"MERCURY_SET_VIREF" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_VOMAXREF,				"MERCURY_SET_VOMAXREF" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_VOMINREF,				"MERCURY_SET_VOMINREF" },
	{ SOLAREDGE_COMMAND_MERCURY_READ_MEAS,					"MERCURY_READ_MEAS" },
	{ SOLAREDGE_COMMAND_MERCURY_CLOSED_LOOP_START,				"MERCURY_CLOSED_LOOP_START" },
	{ SOLAREDGE_COMMAND_MERCURY_OPEN_LOOP_START,				"MERCURY_OPEN_LOOP_START" },
	{ SOLAREDGE_COMMAND_MERCURY_OPEN_LOOP_SET,				"MERCURY_OPEN_LOOP_SET" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_12V_10V,				"MERCURY_SET_12V_10V" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_5V_35V,					"MERCURY_SET_5V_35V" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_VO_RANGE,				"MERCURY_SET_VO_RANGE" },
	{ SOLAREDGE_COMMAND_MERCURY_START_MPPT,					"MERCURY_START_MPPT" },
	{ SOLAREDGE_COMMAND_MERCURY_TX_ENABLE,					"MERCURY_TX_ENABLE" },
	{ SOLAREDGE_COMMAND_MERCURY_TX_TEST,					"MERCURY_TX_TEST" },
	{ SOLAREDGE_COMMAND_MERCURY_RX_TEST,					"MERCURY_RX_TEST" },
	{ SOLAREDGE_COMMAND_MERCURY_FORCE_TELEM,				"MERCURY_FORCE_TELEM" },
	{ SOLAREDGE_COMMAND_MERCURY_READ_SAMPLES_DIRECT,			"MERCURY_READ_SAMPLES_DIRECT" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_OTP_BLOCK,				"MERCURY_SET_OTP_BLOCK" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_CAL_MODE,				"MERCURY_SET_CAL_MODE" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_VI_RANGE,				"MERCURY_SET_VI_RANGE" },
	{ SOLAREDGE_COMMAND_MERCURY_AVG_SAMPLE,					"MERCURY_AVG_SAMPLE" },
	{ SOLAREDGE_COMMAND_MERCURY_GET_TELEM,					"MERCURY_GET_TELEM" },
	{ SOLAREDGE_COMMAND_MERCURY_DISABLE_PROTECTION,				"MERCURY_DISABLE_PROTECTION" },
	{ SOLAREDGE_COMMAND_MERCURY_BYPASS_MODE,				"MERCURY_BYPASS_MODE" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_TEMP_CAL_PIN,				"MERCURY_SET_TEMP_CAL_PIN" },
	{ SOLAREDGE_COMMAND_MERCURY_SAVE_VOLATILE,				"MERCURY_SAVE_VOLATILE" },
	{ SOLAREDGE_COMMAND_MERCURY_BBB_MODE,					"MERCURY_BBB_MODE" },
	{ SOLAREDGE_COMMAND_MERCURY_GET_REG,					"MERCURY_GET_REG" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_RES_CIRC_GPIOS,				"MERCURY_SET_RES_CIRC_GPIOS" },
	{ SOLAREDGE_COMMAND_MERCURY_GET_SNR,					"MERCURY_GET_SNR" },
	{ SOLAREDGE_COMMAND_MERCURY_GET_LOOP_MODE,				"MERCURY_GET_LOOP_MODE" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_REG,					"MERCURY_SET_REG" },
	{ SOLAREDGE_COMMAND_MERCURY_DFT,					"MERCURY_DFT" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_COMM_SW,				"MERCURY_SET_COMM_SW" },
	{ SOLAREDGE_COMMAND_MERCURY_GET_SPI_SAMPLES,				"MERCURY_GET_SPI_SAMPLES" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_DT,					"MERCURY_SET_DT" },
	{ SOLAREDGE_COMMAND_MERCURY_GET_DFT_AVG,				"MERCURY_GET_DFT_AVG" },
	{ SOLAREDGE_COMMAND_MERCURY_CONTROL_TEST,				"MERCURY_CONTROL_TEST" },
	{ SOLAREDGE_COMMAND_MERCURY_GET_STATUS_REG,				"MERCURY_GET_STATUS_REG" },
	{ SOLAREDGE_COMMAND_MERCURY_RESET_STATUS_REG,				"MERCURY_RESET_STATUS_REG" },
	{ SOLAREDGE_COMMAND_MERCURY_SET_DPWM_FREQ,				"MERCURY_SET_DPWM_FREQ" },
	{ SOLAREDGE_COMMAND_RESP_MERCURY_SAMPLES,				"RESP_MERCURY_SAMPLES" },
	{ SOLAREDGE_COMMAND_RESP_MERCURY_MON,					"RESP_MERCURY_MON" },
	{ SOLAREDGE_COMMAND_RESP_MERCURY_TELEM,					"RESP_MERCURY_TELEM" },
	{ SOLAREDGE_COMMAND_RESP_MERCURY_MEAS,					"RESP_MERCURY_MEAS" },
	{ SOLAREDGE_COMMAND_RESP_MERCURY_RX_TEST_RES,				"RESP_MERCURY_RX_TEST_RES" },
	{ SOLAREDGE_COMMAND_RESP_MERCURY_SAMPLES_DIRECT,			"RESP_MERCURY_SAMPLES_DIRECT" },
	{ SOLAREDGE_COMMAND_RESP_MERCURY_AVG_SAMPLE,				"RESP_MERCURY_AVG_SAMPLE" },
	{ SOLAREDGE_COMMAND_RESP_MERCURY_GET_TELEM,				"RESP_MERCURY_GET_TELEM" },
	{ SOLAREDGE_COMMAND_RESP_MERCURY_CONTROL_TEST,				"RESP_MERCURY_CONTROL_TEST" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_READ_ISE_MEAS1,				"VENUSMNGR_READ_ISE_MEAS1" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_READ_ISE_MEAS2,				"VENUSMNGR_READ_ISE_MEAS2" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_READ_SE_MEAS,				"VENUSMNGR_READ_SE_MEAS" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_START_INVERTER,				"VENUSMNGR_START_INVERTER" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_ISE_DUTY_CYCLE,				"VENUSMNGR_ISE_DUTY_CYCLE" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_GET_SYS_STATUS,				"VENUSMNGR_GET_SYS_STATUS" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_GET_TELEM,				"VENUSMNGR_GET_TELEM" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_RX_TEST_INIT,				"VENUSMNGR_RX_TEST_INIT" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_RX_TEST,					"VENUSMNGR_RX_TEST" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_TX_TEST_START,				"VENUSMNGR_TX_TEST_START" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_TX_TEST_STOP,				"VENUSMNGR_TX_TEST_STOP" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_SET_TX_ENABLE,				"VENUSMNGR_SET_TX_ENABLE" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_ENABLE_ISE_WD,				"VENUSMNGR_ENABLE_ISE_WD" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_DISABLE_ISE_WD,				"VENUSMNGR_DISABLE_ISE_WD" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_GET_COUNTRY_CODE,				"VENUSMNGR_GET_COUNTRY_CODE" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_SET_COUNTRY,				"VENUSMNGR_SET_COUNTRY" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_PRIVILEGED_MODE,				"VENUSMNGR_PRIVILEGED_MODE" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_PRIVILEGED_SET_PARAM,			"VENUSMNGR_PRIVILEGED_SET_PARAM" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_PRIVILEGED_GET_EVENT,			"VENUSMNGR_PRIVILEGED_GET_EVENT" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_PRIVILEGED_GET_STATUS,			"VENUSMNGR_PRIVILEGED_GET_STATUS" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_CURRENT_MODEM_START,			"VENUSMNGR_CURRENT_MODEM_START" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_CURRENT_MODEM_SEND,			"VENUSMNGR_CURRENT_MODEM_SEND" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_CURRENT_MODEM_SEND_PAIRING,		"VENUSMNGR_CURRENT_MODEM_SEND_PAIRING" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_CURRENT_MODEM_GET_STATUS,			"VENUSMNGR_CURRENT_MODEM_GET_STATUS" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_KA_DATA_SEND,				"VENUSMNGR_KA_DATA_SEND" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_CURRENT_MODEM_END_PAIRING,		"VENUSMNGR_CURRENT_MODEM_END_PAIRING" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_FORCE_GRID_MON,				"VENUSMNGR_FORCE_GRID_MON" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_FORCE_SKIP_GRID_MON,			"VENUSMNGR_FORCE_SKIP_GRID_MON" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_START_SUPERVISE,				"VENUSMNGR_START_SUPERVISE" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_READ_A2D_MEAS,				"VENUSMNGR_READ_A2D_MEAS" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_GET_COUNTRY_DEFAULTS,			"VENUSMNGR_GET_COUNTRY_DEFAULTS" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_SET_PRODUCT_MODEL,			"VENUSMNGR_SET_PRODUCT_MODEL" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_GET_PRODUCT_MODEL,			"VENUSMNGR_GET_PRODUCT_MODEL" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_SET_DYNAMIC_INVPWR_PARAM,			"VENUSMNGR_SET_DYNAMIC_INVPWR_PARAM" },
	{ SOLAREDGE_COMMAND_INVERTER_ENTER_BURN_INVPWR_MODE,			"INVERTER_ENTER_BURN_INVPWR_MODE" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_MPPT_TRAVEL,				"VENUSMNGR_MPPT_TRAVEL" },
	{ SOLAREDGE_COMMAND_VENUSMNGR_SET_PWR_PARAM,				"VENUSMNGR_SET_PWR_PARAM" },
	{ SOLAREDGE_COMMAND_INVERTER_CURRENT_MODEM_SET_DATA_BIT,		"INVERTER_CURRENT_MODEM_SET_DATA_BIT" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_READ_ISE_MEAS1,			"RESP_VENUSMNGR_READ_ISE_MEAS1" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_READ_ISE_MEAS2,			"RESP_VENUSMNGR_READ_ISE_MEAS2" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_READ_SE_MEAS,			"RESP_VENUSMNGR_READ_SE_MEAS" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_GET_SYS_STATUS,			"RESP_VENUSMNGR_GET_SYS_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_GET_TELEM,				"RESP_VENUSMNGR_GET_TELEM" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_RX_TEST,				"RESP_VENUSMNGR_RX_TEST" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_GET_COUNTRY_CODE,			"RESP_VENUSMNGR_GET_COUNTRY_CODE" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_PRIVILEGED_GET_EVENT,		"RESP_VENUSMNGR_PRIVILEGED_GET_EVENT" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_PRIVILEGED_GET_STATUS,		"RESP_VENUSMNGR_PRIVILEGED_GET_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_CURRENT_MODEM_GET_STATUS,		"RESP_VENUSMNGR_CURRENT_MODEM_GET_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_READ_A2D_MEAS,			"RESP_VENUSMNGR_READ_A2D_MEAS" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_GET_COUNTRY_DEFAULTS,		"RESP_VENUSMNGR_GET_COUNTRY_DEFAULTS" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_GET_PRODUCT_MODEL,			"RESP_VENUSMNGR_GET_PRODUCT_MODEL" },
	{ SOLAREDGE_COMMAND_RESP_VENUSMNGR_SET_DYNAMIC_ISE_PARAM,		"RESP_VENUSMNGR_SET_DYNAMIC_ISE_PARAM" },
	{ SOLAREDGE_COMMAND_POLESTAR_TELEMS_START,				"POLESTAR_TELEMS_START" },
	{ SOLAREDGE_COMMAND_POLESTAR_TELEMS_STOP,				"POLESTAR_TELEMS_STOP" },
	{ SOLAREDGE_COMMAND_POLESTAR_MASTER_GRANT,				"POLESTAR_MASTER_GRANT" },
	{ SOLAREDGE_COMMAND_POLESTAR_RTC_SET,					"POLESTAR_RTC_SET" },
	{ SOLAREDGE_COMMAND_POLESTAR_TEST_RAM,					"POLESTAR_TEST_RAM" },
	{ SOLAREDGE_COMMAND_POLESTAR_TEST_FLASH,				"POLESTAR_TEST_FLASH" },
	{ SOLAREDGE_COMMAND_POLESTAR_MAC_ADDR_GET,				"POLESTAR_MAC_ADDR_GET" },
	{ SOLAREDGE_COMMAND_POLESTAR_IP_ADDR_GET,				"POLESTAR_IP_ADDR_GET" },
	{ SOLAREDGE_COMMAND_POLESTAR_SLAVE_ID_DETECT_INIT,			"POLESTAR_SLAVE_ID_DETECT_INIT" },
	{ SOLAREDGE_COMMAND_POLESTAR_SLAVE_ID_DETECT_GET_ID,			"POLESTAR_SLAVE_ID_DETECT_GET_ID" },
	{ SOLAREDGE_COMMAND_POLESTAR_SLAVE_ID_DETECT_STOP,			"POLESTAR_SLAVE_ID_DETECT_STOP" },
	{ SOLAREDGE_COMMAND_POLESTAR_UART_ZB_BRIDGE,				"POLESTAR_UART_ZB_BRIDGE" },
	{ SOLAREDGE_COMMAND_POLESTAR_SEND_PING,					"POLESTAR_SEND_PING" },
	{ SOLAREDGE_COMMAND_POLESTAR_LCD_TEST_MODE,				"POLESTAR_LCD_TEST_MODE" },
	{ SOLAREDGE_COMMAND_POLESTAR_CONFTOOL_START,				"POLESTAR_CONFTOOL_START" },
	{ SOLAREDGE_COMMAND_POLESTAR_ETHERNET_STAT,				"POLESTAR_ETHERNET_STAT" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_FIFO_FLASH_INFO,			"POLESTAR_GET_FIFO_FLASH_INFO" },
	{ SOLAREDGE_COMMAND_POLESTAR_RESET_FIFO_FLASH,				"POLESTAR_RESET_FIFO_FLASH" },
	{ SOLAREDGE_COMMAND_POLESTAR_RESET_FLASH,				"POLESTAR_RESET_FLASH" },
	{ SOLAREDGE_COMMAND_POLESTAR_RS485_MSTR_SLV_DET_START,			"POLESTAR_RS485_MSTR_SLV_DET_START" },
	{ SOLAREDGE_COMMAND_POLESTAR_RS485_MSTR_SLV_DET_STATUS,			"POLESTAR_RS485_MSTR_SLV_DET_STATUS" },
	{ SOLAREDGE_COMMAND_POLESTAR_UART_ZB_SET,				"POLESTAR_UART_ZB_SET" },
	{ SOLAREDGE_COMMAND_POLESTAR_TCP_TEST,					"POLESTAR_TCP_TEST" },
	{ SOLAREDGE_COMMAND_POLESTAR_TIMER_ADVANCE,				"POLESTAR_TIMER_ADVANCE" },
	{ SOLAREDGE_COMMAND_POLESTAR_ERASE_FLASH_FIFO_FAST,			"POLESTAR_ERASE_FLASH_FIFO_FAST" },
	{ SOLAREDGE_COMMAND_POLESTAR_SELF_KA,					"POLESTAR_SELF_KA" },
	{ SOLAREDGE_COMMAND_POLESTAR_ISE_BRIDGE,				"POLESTAR_ISE_BRIDGE" },
	{ SOLAREDGE_COMMAND_POLESTAR_ERASE_STATISTICS,				"POLESTAR_ERASE_STATISTICS" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_POK_STATUS,				"POLESTAR_GET_POK_STATUS" },
	{ SOLAREDGE_COMMAND_POLESTAR_INVERTER_HW_RESET,				"POLESTAR_INVERTER_HW_RESET" },
	{ SOLAREDGE_COMMAND_POLESTAR_ZB_PRESENT_STATUS,				"POLESTAR_ZB_PRESENT_STATUS" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_ALL_SUPPORTED_LANGUAGES_INDEXES,	"POLESTAR_GET_ALL_SUPPORTED_LANGUAGES_INDEXES" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_ALL_SUPPORTED_GSM_MODEMS_INDEXES,	"POLESTAR_GET_ALL_SUPPORTED_GSM_MODEMS_INDEXES" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_S_OK_STATUS,				"POLESTAR_GET_S_OK_STATUS" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_ENERGY_STATISTICS_STATUS,		"POLESTAR_GET_ENERGY_STATISTICS_STATUS" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_GSM_PRESENT_STATUS,			"POLESTAR_GET_GSM_PRESENT_STATUS" },
	{ SOLAREDGE_COMMAND_POLESTAR_SET_STATISTICS_ELEMENT,			"POLESTAR_SET_STATISTICS_ELEMENT" },
	{ SOLAREDGE_COMMAND_POLESTAR_GEMINI_RS485_MSTR_SLV_DET_START,		"POLESTAR_GEMINI_RS485_MSTR_SLV_DET_START" },
	{ SOLAREDGE_COMMAND_POLESTAR_GEMINI_RS485_MSTR_SLV_DET_STATUS,		"POLESTAR_GEMINI_RS485_MSTR_SLV_DET_STATUS" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_GEMINI_GFD_STATUS,			"POLESTAR_GET_GEMINI_GFD_STATUS" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_ERROR_LOG,				"POLESTAR_GET_ERROR_LOG" },
	{ SOLAREDGE_COMMAND_POLESTAR_BLOCK_SERVER_CONTROL,			"POLESTAR_BLOCK_SERVER_CONTROL" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_SERVER_CONTROL_STATUS,			"POLESTAR_GET_SERVER_CONTROL_STATUS" },
	{ SOLAREDGE_COMMAND_POLESTAR_TEST_SD_FLASH,				"POLESTAR_TEST_SD_FLASH" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_WARNING_LOG,				"POLESTAR_GET_WARNING_LOG" },
	{ SOLAREDGE_COMMAND_POLESTAR_RESET_MODBUS_DEVICE_DATA,			"POLESTAR_RESET_MODBUS_DEVICE_DATA" },
	{ SOLAREDGE_COMMAND_POLESTAR_TURN_OFF_INTERNAL_SRAM_BATTERY_BACKUP,	"POLESTAR_TURN_OFF_INTERNAL_SRAM_BATTERY_BACKUP" },
	{ SOLAREDGE_COMMAND_POLESTAR_WRITE_LCD,					"POLESTAR_WRITE_LCD" },
	{ SOLAREDGE_COMMAND_POLESTAR_READ_LAST_BUTTONS,				"POLESTAR_READ_LAST_BUTTONS" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_STATISTICS_ELEMENT,			"POLESTAR_GET_STATISTICS_ELEMENT" },
	{ SOLAREDGE_COMMAND_POLESTAR_SEND_POWER_REDUCER_SLAVE_PACKET,		"POLESTAR_SEND_POWER_REDUCER_SLAVE_PACKET" },
	{ SOLAREDGE_COMMAND_POLESTAR_SEND_POWER_REDUCER_MASTER_PACKET,		"POLESTAR_SEND_POWER_REDUCER_MASTER_PACKET" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_WIFI_PRESENT_STATUS,			"POLESTAR_GET_WIFI_PRESENT_STATUS" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_PORT_EXPANDER_GPIO_DATA,		"POLESTAR_GET_PORT_EXPANDER_GPIO_DATA" },
	{ SOLAREDGE_COMMAND_POLESTAR_SET_PORT_EXPANDER_GPIO_DATA,		"POLESTAR_SET_PORT_EXPANDER_GPIO_DATA" },
	{ SOLAREDGE_COMMAND_POLESTAR_READ_LCD,					"POLESTAR_READ_LCD" },
	{ SOLAREDGE_COMMAND_POLESTAR_SIMULATE_BUTTON_PRESSING,			"POLESTAR_SIMULATE_BUTTON_PRESSING" },
	{ SOLAREDGE_COMMAND_POLESTAR_INV_ACTIVATE,				"POLESTAR_INV_ACTIVATE" },
	{ SOLAREDGE_COMMAND_POLESTAR_MODBUS_SLAVE_PACKET,			"POLESTAR_MODBUS_SLAVE_PACKET" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_BUTTON_STATE,				"POLESTAR_GET_BUTTON_STATE" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_A2D_VALS,				"POLESTAR_GET_A2D_VALS" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_OPMODE,				"POLESTAR_GET_OPMODE" },
	{ SOLAREDGE_COMMAND_POLESTAR_SET_BACKLIGHT,				"POLESTAR_SET_BACKLIGHT" },
	{ SOLAREDGE_COMMAND_POLESTAR_READ_FIFO_PAGE,				"POLESTAR_READ_FIFO_PAGE" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_CURRENT_SCREEN_INDEX,			"POLESTAR_GET_CURRENT_SCREEN_INDEX" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_IDENTITY,				"POLESTAR_GET_IDENTITY" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_SUPPORTED_COMMANDS,			"POLESTAR_GET_SUPPORTED_COMMANDS" },
	{ SOLAREDGE_COMMAND_POLESTAR_PAIRING_START,				"POLESTAR_PAIRING_START" },
	{ SOLAREDGE_COMMAND_POLESTAR_PAIRING_STATUS,				"POLESTAR_PAIRING_STATUS" },
	{ SOLAREDGE_COMMAND_POLESTAR_PRODUCT_RESET,				"POLESTAR_PRODUCT_RESET" },
	{ SOLAREDGE_COMMAND_POLESTAR_PLC_CMD_EXECUTE,				"POLESTAR_PLC_CMD_EXECUTE" },
	{ SOLAREDGE_COMMAND_POLESTAR_GET_STATUS,				"POLESTAR_GET_STATUS" },
	{ SOLAREDGE_COMMAND_POLESTAR_FIRE_SAFETY_LOCK_MASTER,			"POLESTAR_FIRE_SAFETY_LOCK_MASTER" },
	{ SOLAREDGE_COMMAND_POLESTAR_FIRE_SAFETY_LOCK_SLAVE,			"POLESTAR_FIRE_SAFETY_LOCK_SLAVE" },
	{ SOLAREDGE_COMMAND_POLESTAR_FIRE_SAFETY_REPORT,			"POLESTAR_FIRE_SAFETY_REPORT" },
	{ SOLAREDGE_COMMAND_POLESTAR_UART_BRIDGE_INIT,				"POLESTAR_UART_BRIDGE_INIT" },
	{ SOLAREDGE_COMMAND_POLESTAR_SEND_UART_DATA,				"POLESTAR_SEND_UART_DATA" },
	{ SOLAREDGE_COMMAND_POLESTAR_LED_TEST,					"POLESTAR_LED_TEST" },
	{ SOLAREDGE_COMMAND_POLESTAR_SEND_FAKE_TELEMS,				"POLESTAR_SEND_FAKE_TELEMS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_RTC_SET,				"RESP_POLESTAR_RTC_SET" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_MAC_ADDR_GET,				"RESP_POLESTAR_MAC_ADDR_GET" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_IP_ADDR_GET,				"RESP_POLESTAR_IP_ADDR_GET" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_SEND_PING,				"RESP_POLESTAR_SEND_PING" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_ETHERNET_STAT,			"RESP_POLESTAR_ETHERNET_STAT" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_FIFO_FLASH_INFO,			"RESP_POLESTAR_GET_FIFO_FLASH_INFO" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_RS485_MSTR_SLV_DET_STATUS,		"RESP_POLESTAR_RS485_MSTR_SLV_DET_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_TCP_TEST_RESP,			"RESP_POLESTAR_TCP_TEST_RESP" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_POK_STATUS,			"RESP_POLESTAR_GET_POK_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_INVERTER_HW_RESET,			"RESP_POLESTAR_INVERTER_HW_RESET" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_ALL_SUPPORTED_LANGUAGES_INDEXES,	"RESP_POLESTAR_GET_ALL_SUPPORTED_LANGUAGES_INDEXES" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_ALL_SUPPORTED_GSM_MODEMS_INDEXES,	"RESP_POLESTAR_GET_ALL_SUPPORTED_GSM_MODEMS_INDEXES" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_S_OK_STATUS,			"RESP_POLESTAR_GET_S_OK_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_ENERGY_STATISTICS_STATUS,		"RESP_POLESTAR_GET_ENERGY_STATISTICS_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_GSM_PRESENT_STATUS,		"RESP_POLESTAR_GET_GSM_PRESENT_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GEMINI_RS485_MSTR_SLV_DET_STATUS,	"RESP_POLESTAR_GEMINI_RS485_MSTR_SLV_DET_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_GEMINI_GFD_STATUS,		"RESP_POLESTAR_GET_GEMINI_GFD_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_ERROR_LOG,			"RESP_POLESTAR_GET_ERROR_LOG" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_SERVER_CONTROL_STATUS,		"RESP_POLESTAR_GET_SERVER_CONTROL_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_WARNING_LOG,			"RESP_POLESTAR_GET_WARNING_LOG" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_READ_LAST_BUTTONS,			"RESP_POLESTAR_READ_LAST_BUTTONS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_STATISTICS_ELEMENT,		"RESP_POLESTAR_GET_STATISTICS_ELEMENT" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_WIFI_PRESENT_STATUS,		"RESP_POLESTAR_GET_WIFI_PRESENT_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_PORT_EXPANDER_GPIO_DATA,		"RESP_POLESTAR_GET_PORT_EXPANDER_GPIO_DATA" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_READ_LCD,				"RESP_POLESTAR_READ_LCD" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_MODBUS_SLAVE_PACKET,			"RESP_POLESTAR_MODBUS_SLAVE_PACKET" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_MASTER_GRANT_ACK,			"RESP_POLESTAR_MASTER_GRANT_ACK" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_IDENTITY,				"RESP_POLESTAR_GET_IDENTITY" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_SUPPORTED_COMMANDS,		"RESP_POLESTAR_GET_SUPPORTED_COMMANDS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_PAIRING_START,			"RESP_POLESTAR_PAIRING_START" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_PAIRING_STATUS,			"RESP_POLESTAR_PAIRING_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_GET_STATUS,				"RESP_POLESTAR_GET_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_FIRE_SAFETY_REPORT,			"RESP_POLESTAR_FIRE_SAFETY_REPORT" },
	{ SOLAREDGE_COMMAND_RESP_POLESTAR_SEND_UART_DATA,			"RESP_POLESTAR_SEND_UART_DATA" },
	{ SOLAREDGE_COMMAND_SUNTRACER_READ_FLASH,				"SUNTRACER_READ_FLASH" },
	{ SOLAREDGE_COMMAND_SUNTRACER_START,					"SUNTRACER_START" },
	{ SOLAREDGE_COMMAND_SUNTRACER_SET_RTC,					"SUNTRACER_SET_RTC" },
	{ SOLAREDGE_COMMAND_SUNTRACER_DEL_FLASH,				"SUNTRACER_DEL_FLASH" },
	{ SOLAREDGE_COMMAND_SUNTRACER_DEL_FLASH_SECTOR,				"SUNTRACER_DEL_FLASH_SECTOR" },
	{ SOLAREDGE_COMMAND_RESP_SUNTRACER_TRACE,				"RESP_SUNTRACER_TRACE" },
	{ SOLAREDGE_COMMAND_RESP_SUNTRACER_FLASH,				"RESP_SUNTRACER_FLASH" },
	{ SOLAREDGE_COMMAND_SERVER_POST_DATA,					"SERVER_POST_DATA" },
	{ SOLAREDGE_COMMAND_SERVER_GET_GMT,					"SERVER_GET_GMT" },
	{ SOLAREDGE_COMMAND_SERVER_GET_NAME,					"SERVER_GET_NAME" },
	{ SOLAREDGE_COMMAND_SERVER_SET_KEY,					"SERVER_SET_KEY" },
	{ SOLAREDGE_COMMAND_RESP_SERVER_GMT,					"RESP_SERVER_GMT" },
	{ SOLAREDGE_COMMAND_RESP_SERVER_NAME,					"RESP_SERVER_NAME" },
	{ SOLAREDGE_COMMAND_RESP_CONFTOOL_PLC_DATA,				"RESP_CONFTOOL_PLC_DATA" },
	{ SOLAREDGE_COMMAND_JUPMNGR_READ_JUPPWR_MEAS1,				"JUPMNGR_READ_JUPPWR_MEAS1" },
	{ SOLAREDGE_COMMAND_JUPMNGR_READ_JUPPWR_MEAS2,				"JUPMNGR_READ_JUPPWR_MEAS2" },
	{ SOLAREDGE_COMMAND_JUPMNGR_READ_JUPPWR_MEAS3,				"JUPMNGR_READ_JUPPWR_MEAS3" },
	{ SOLAREDGE_COMMAND_JUPMNGR_READ_JUPPWR_MEAS4,				"JUPMNGR_READ_JUPPWR_MEAS4" },
	{ SOLAREDGE_COMMAND_JUPMNGR_READ_JUPPWR_MEAS5,				"JUPMNGR_READ_JUPPWR_MEAS5" },
	{ SOLAREDGE_COMMAND_JUPMNGR_READ_MEAS,					"JUPMNGR_READ_MEAS" },
	{ SOLAREDGE_COMMAND_JUPMNGR_GET_SYS_STATUS,				"JUPMNGR_GET_SYS_STATUS" },
	{ SOLAREDGE_COMMAND_JUPMNGR_GET_TELEM,					"JUPMNGR_GET_TELEM" },
	{ SOLAREDGE_COMMAND_JUPMNGR_GET_COUNTRY_CODE,				"JUPMNGR_GET_COUNTRY_CODE" },
	{ SOLAREDGE_COMMAND_JUPMNGR_SET_COUNTRY,				"JUPMNGR_SET_COUNTRY" },
	{ SOLAREDGE_COMMAND_JUPMNGR_GET_COUNTRY_DEFAULTS,			"JUPMNGR_GET_COUNTRY_DEFAULTS" },
	{ SOLAREDGE_COMMAND_JUPMNGR_PRIVILEGED_MODE,				"JUPMNGR_PRIVILEGED_MODE" },
	{ SOLAREDGE_COMMAND_JUPMNGR_PRIVILEGED_SET_PARAM,			"JUPMNGR_PRIVILEGED_SET_PARAM" },
	{ SOLAREDGE_COMMAND_JUPMNGR_PRIVILEGED_GET_EVENT,			"JUPMNGR_PRIVILEGED_GET_EVENT" },
	{ SOLAREDGE_COMMAND_JUPMNGR_PRIVILEGED_GET_STATUS,			"JUPMNGR_PRIVILEGED_GET_STATUS" },
	{ SOLAREDGE_COMMAND_JUPMNGR_SET_PRODUCT_MODEL,				"JUPMNGR_SET_PRODUCT_MODEL" },
	{ SOLAREDGE_COMMAND_JUPMNGR_GET_PRODUCT_MODEL,				"JUPMNGR_GET_PRODUCT_MODEL" },
	{ SOLAREDGE_COMMAND_JUPMNGR_DYNAMIC_SET_INVPWR_PARAM,			"JUPMNGR_DYNAMIC_SET_INVPWR_PARAM" },
	{ SOLAREDGE_COMMAND_JUPMNGR_GET_INVPWR_PARAM_TYPE,			"JUPMNGR_GET_INVPWR_PARAM_TYPE" },
	{ SOLAREDGE_COMMAND_JUPMNGR_GET_FANS_STATUS,				"JUPMNGR_GET_FANS_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_READ_JUPPWR_MEAS1,			"RESP_JUPMNGR_READ_JUPPWR_MEAS1" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_READ_JUPPWR_MEAS2,			"RESP_JUPMNGR_READ_JUPPWR_MEAS2" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_READ_JUPPWR_MEAS3,			"RESP_JUPMNGR_READ_JUPPWR_MEAS3" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_READ_JUPPWR_MEAS4,			"RESP_JUPMNGR_READ_JUPPWR_MEAS4" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_READ_JUPPWR_MEAS5,			"RESP_JUPMNGR_READ_JUPPWR_MEAS5" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_READ_MEAS,				"RESP_JUPMNGR_READ_MEAS" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_SYS_STATUS,			"RESP_JUPMNGR_GET_SYS_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_TELEM,				"RESP_JUPMNGR_GET_TELEM" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_COUNTRY_CODE,			"RESP_JUPMNGR_GET_COUNTRY_CODE" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_COUNTRY_DEFAULTS,			"RESP_JUPMNGR_GET_COUNTRY_DEFAULTS" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_PRIVILEGED_GET_EVENT,			"RESP_JUPMNGR_PRIVILEGED_GET_EVENT" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_PRIVILEGED_GET_STATUS,			"RESP_JUPMNGR_PRIVILEGED_GET_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_PRODUCT_MODEL,			"RESP_JUPMNGR_GET_PRODUCT_MODEL" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_INVPWR_PARAM_TYPE,			"RESP_JUPMNGR_GET_INVPWR_PARAM_TYPE" },
	{ SOLAREDGE_COMMAND_RESP_JUPMNGR_GET_FANS_STATUS,			"RESP_JUPMNGR_GET_FANS_STATUS" },
	{ SOLAREDGE_COMMAND_INVERTER_TURN_15V_ON,				"INVERTER_TURN_15V_ON" },
	{ SOLAREDGE_COMMAND_INVERTER_TURN_15V_OFF,				"INVERTER_TURN_15V_OFF" },
	{ SOLAREDGE_COMMAND_INVERTER_ENABLE_RELAYS,				"INVERTER_ENABLE_RELAYS" },
	{ SOLAREDGE_COMMAND_INVERTER_DISABLE_RELAYS,				"INVERTER_DISABLE_RELAYS" },
	{ SOLAREDGE_COMMAND_INVERTER_DYNAMIC_POWER_LIMIT,			"INVERTER_DYNAMIC_POWER_LIMIT" },
	{ SOLAREDGE_COMMAND_INVERTER_IVTRACE_START,				"INVERTER_IVTRACE_START" },
	{ SOLAREDGE_COMMAND_INVERTER_GRID_TRIP_TEST,				"INVERTER_GRID_TRIP_TEST" },
	{ SOLAREDGE_COMMAND_INVERTER_SET_LMVGC_PARAMS1,				"INVERTER_SET_LMVGC_PARAMS1" },
	{ SOLAREDGE_COMMAND_INVERTER_GET_LMVGC_PARAMS1,				"INVERTER_GET_LMVGC_PARAMS1" },
	{ SOLAREDGE_COMMAND_INVERTER_SET_PWR_GAIN_PARAMS,			"INVERTER_SET_PWR_GAIN_PARAMS" },
	{ SOLAREDGE_COMMAND_INVERTER_SET_LMVGC_PARAMS2,				"INVERTER_SET_LMVGC_PARAMS2" },
	{ SOLAREDGE_COMMAND_INVERTER_GET_LMVGC_PARAMS2,				"INVERTER_GET_LMVGC_PARAMS2" },
	{ SOLAREDGE_COMMAND_INVERTER_SET_LMVGC_PARAMS3,				"INVERTER_SET_LMVGC_PARAMS3" },
	{ SOLAREDGE_COMMAND_INVERTER_GET_LMVGC_PARAMS3,				"INVERTER_GET_LMVGC_PARAMS3" },
	{ SOLAREDGE_COMMAND_INVERTER_LOCK_IN,					"INVERTER_LOCK_IN" },
	{ SOLAREDGE_COMMAND_INVERTER_LOCK_OUT,					"INVERTER_LOCK_OUT" },
	{ SOLAREDGE_COMMAND_INVERTER_GET_VDC,					"INVERTER_GET_VDC" },
	{ SOLAREDGE_COMMAND_INVERTER_PAIRING_DO_NOTHING,			"INVERTER_PAIRING_DO_NOTHING" },
	{ SOLAREDGE_COMMAND_INVERTER_PAIRING_DO_SAFETY,				"INVERTER_PAIRING_DO_SAFETY" },
	{ SOLAREDGE_COMMAND_RESP_INVERTER_DYNAMIC_POWER_LIMIT,			"RESP_INVERTER_DYNAMIC_POWER_LIMIT" },
	{ SOLAREDGE_COMMAND_RESP_INVERTER_GET_LMVGC_PARAMS,			"RESP_INVERTER_GET_LMVGC_PARAMS" },
	{ SOLAREDGE_COMMAND_VEGA_READ_MEAS,					"VEGA_READ_MEAS" },
	{ SOLAREDGE_COMMAND_VEGA_GET_SYS_STATUS,				"VEGA_GET_SYS_STATUS" },
	{ SOLAREDGE_COMMAND_VEGA_GET_TELEM,					"VEGA_GET_TELEM" },
	{ SOLAREDGE_COMMAND_VEGA_GET_MAX_VDC_VALUE,				"VEGA_GET_MAX_VDC_VALUE" },
	{ SOLAREDGE_COMMAND_VEGA_SET_MAX_VDC_VALUE,				"VEGA_SET_MAX_VDC_VALUE" },
	{ SOLAREDGE_COMMAND_VEGA_RELAY_SET,					"VEGA_RELAY_SET" },
	{ SOLAREDGE_COMMAND_VEGA_SET_OPMODE,					"VEGA_SET_OPMODE" },
	{ SOLAREDGE_COMMAND_VEGA_GET_OPMODE,					"VEGA_GET_OPMODE" },
	{ SOLAREDGE_COMMAND_VEGA_SET_RANGE,					"VEGA_SET_RANGE" },
	{ SOLAREDGE_COMMAND_RESP_VEGA_READ_MEAS,				"RESP_VEGA_READ_MEAS" },
	{ SOLAREDGE_COMMAND_RESP_VEGA_GET_SYS_STATUS,				"RESP_VEGA_GET_SYS_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_VEGA_GET_TELEM,				"RESP_VEGA_GET_TELEM" },
	{ SOLAREDGE_COMMAND_RESP_VEGA_GET_MAX_VDC_VALUE,			"RESP_VEGA_GET_MAX_VDC_VALUE" },
	{ SOLAREDGE_COMMAND_COMBI_PAUSE_MONITORING,				"COMBI_PAUSE_MONITORING" },
	{ SOLAREDGE_COMMAND_COMBI_SET_TIME_STAMP,				"COMBI_SET_TIME_STAMP" },
	{ SOLAREDGE_COMMAND_COMBI_RCD_CALIBRATION,				"COMBI_RCD_CALIBRATION" },
	{ SOLAREDGE_COMMAND_COMBI_GET_TELEM,					"COMBI_GET_TELEM" },
	{ SOLAREDGE_COMMAND_COMBI_FORCE_TELEM,					"COMBI_FORCE_TELEM" },
	{ SOLAREDGE_COMMAND_COMBI_SWITCHES_CONNECT,				"COMBI_SWITCHES_CONNECT" },
	{ SOLAREDGE_COMMAND_COMBI_SWITCHES_DISCONNECT,				"COMBI_SWITCHES_DISCONNECT" },
	{ SOLAREDGE_COMMAND_COMBI_SWITCHES_CONNECT_ALL,				"COMBI_SWITCHES_CONNECT_ALL" },
	{ SOLAREDGE_COMMAND_COMBI_SWITCHES_DISCONNECT_ALL,			"COMBI_SWITCHES_DISCONNECT_ALL" },
	{ SOLAREDGE_COMMAND_COMBI_RCD_TEST_EXECUTE,				"COMBI_RCD_TEST_EXECUTE" },
	{ SOLAREDGE_COMMAND_COMBI_RELAYS_TEST_EXECUTE,				"COMBI_RELAYS_TEST_EXECUTE" },
	{ SOLAREDGE_COMMAND_COMBI_GET_COMBISTRING_PARAM,			"COMBI_GET_COMBISTRING_PARAM" },
	{ SOLAREDGE_COMMAND_COMBI_SET_COMBISTRING_PARAM,			"COMBI_SET_COMBISTRING_PARAM" },
	{ SOLAREDGE_COMMAND_COMBI_GET_ALL_COMBISTRING_PARAMS,			"COMBI_GET_ALL_COMBISTRING_PARAMS" },
	{ SOLAREDGE_COMMAND_COMBI_GET_ALL_COMBI_PARAMS,				"COMBI_GET_ALL_COMBI_PARAMS" },
	{ SOLAREDGE_COMMAND_COMBI_READ_MEASUREMENTS,				"COMBI_READ_MEASUREMENTS" },
	{ SOLAREDGE_COMMAND_COMBI_GET_STRING_STATUS,				"COMBI_GET_STRING_STATUS" },
	{ SOLAREDGE_COMMAND_COMBI_GET_COMBI_STATUS,				"COMBI_GET_COMBI_STATUS" },
	{ SOLAREDGE_COMMAND_COMBI_GET_ACTIVE_STRINGS,				"COMBI_GET_ACTIVE_STRINGS" },
	{ SOLAREDGE_COMMAND_COMBI_FWD_STRING_TELEM,				"COMBI_FWD_STRING_TELEM" },
	{ SOLAREDGE_COMMAND_COMBI_FWD_COMBI_TELEM,				"COMBI_FWD_COMBI_TELEM" },
	{ SOLAREDGE_COMMAND_COMBI_GET_UNIFIED_STRING_STATUS,			"COMBI_GET_UNIFIED_STRING_STATUS" },
	{ SOLAREDGE_COMMAND_COMBI_GET_UNIFIED_COMBI_STATUS,			"COMBI_GET_UNIFIED_COMBI_STATUS" },
	{ SOLAREDGE_COMMAND_COMBI_CHECK_INNER_PROTOCOL,				"COMBI_CHECK_INNER_PROTOCOL" },
	{ SOLAREDGE_COMMAND_COMBI_SWITCHES_CONNECT_RELAY,			"COMBI_SWITCHES_CONNECT_RELAY" },
	{ SOLAREDGE_COMMAND_COMBI_SWITCHES_DISCONNECT_RELAY,			"COMBI_SWITCHES_DISCONNECT_RELAY" },
	{ SOLAREDGE_COMMAND_COMBI_GET_GEMINI_STRING_IDS,			"COMBI_GET_GEMINI_STRING_IDS" },
	{ SOLAREDGE_COMMAND_COMBI_GET_ALL_SWITCHES_STATUS,			"COMBI_GET_ALL_SWITCHES_STATUS" },
	{ SOLAREDGE_COMMAND_COMBI_SET_RCD_TEST_PIN,				"COMBI_SET_RCD_TEST_PIN" },
	{ SOLAREDGE_COMMAND_COMBI_RELAYS_TEST_CHECK_CONDS,			"COMBI_RELAYS_TEST_CHECK_CONDS" },
	{ SOLAREDGE_COMMAND_RESP_COMBI_GET_TELEM,				"RESP_COMBI_GET_TELEM" },
	{ SOLAREDGE_COMMAND_RESP_COMBI_GET_STRING_STATUS,			"RESP_COMBI_GET_STRING_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_COMBI_GET_COMBI_STATUS,			"RESP_COMBI_GET_COMBI_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_COMBI_GET_ACTIVE_STRINGS,			"RESP_COMBI_GET_ACTIVE_STRINGS" },
	{ SOLAREDGE_COMMAND_RESP_COMBI_GET_UNIFIED_STRING_STATUS,		"RESP_COMBI_GET_UNIFIED_STRING_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_COMBI_GET_UNIFIED_COMBI_STATUS,		"RESP_COMBI_GET_UNIFIED_COMBI_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_COMBI_GET_GEMINI_STRING_IDS,			"RESP_COMBI_GET_GEMINI_STRING_IDS" },
	{ SOLAREDGE_COMMAND_INVPWR_GET_ERROR_STATUS,				"INVPWR_GET_ERROR_STATUS" },
	{ SOLAREDGE_COMMAND_INVPWR_GET_STATUS,					"INVPWR_GET_STATUS" },
	{ SOLAREDGE_COMMAND_INVPWR_GO,						"INVPWR_GO" },
	{ SOLAREDGE_COMMAND_INVPWR_HALT,					"INVPWR_HALT" },
	{ SOLAREDGE_COMMAND_INVPWR_CONST_DUTY_CYCLE,				"INVPWR_CONST_DUTY_CYCLE" },
	{ SOLAREDGE_COMMAND_INVPWR_DUMY_ERROR,					"INVPWR_DUMY_ERROR" },
	{ SOLAREDGE_COMMAND_INVPWR_PAIRING_SET_STATE,				"INVPWR_PAIRING_SET_STATE" },
	{ SOLAREDGE_COMMAND_INVPWR_TEST_IAC_CONTROL,				"INVPWR_TEST_IAC_CONTROL" },
	{ SOLAREDGE_COMMAND_RESP_INVPWR_GET_ERROR_STATUS,			"RESP_INVPWR_GET_ERROR_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_INVPWR_GET_STATUS,				"RESP_INVPWR_GET_STATUS" },
	{ SOLAREDGE_COMMAND_RESP_INVPWR_GO,					"RESP_INVPWR_GO" },
	{ SOLAREDGE_COMMAND_RESP_INVPWR_HALT,					"RESP_INVPWR_HALT" },
	{ SOLAREDGE_COMMAND_RESP_INVPWR_CONST_DUTY_CYCLE,			"RESP_INVPWR_CONST_DUTY_CYCLE" },
	{ SOLAREDGE_COMMAND_RESP_INVPWR_DUMY_ERROR,				"RESP_INVPWR_DUMY_ERROR" },
	{ SOLAREDGE_COMMAND_BOOTLOADER_SECURE,					"BOOTLOADER_SECURE" },
	{ SOLAREDGE_COMMAND_BOOTLOADER_UNSECURE,				"BOOTLOADER_UNSECURE" },
	{ SOLAREDGE_COMMAND_ACTIVATOR_ACTIVATE,					"ACTIVATOR_ACTIVATE" },
	{ SOLAREDGE_COMMAND_ACTIVATOR_GET_ADC_SAMPLES,				"ACTIVATOR_GET_ADC_SAMPLES" },
	{ SOLAREDGE_COMMAND_ACTIVATOR_SET_VO_RANGE,				"ACTIVATOR_SET_VO_RANGE" },
	{ SOLAREDGE_COMMAND_ACTIVATOR_GET_AVG_SAMPLES,				"ACTIVATOR_GET_AVG_SAMPLES" },
	{ SOLAREDGE_COMMAND_ACTIVATOR_TX_TEST,					"ACTIVATOR_TX_TEST" },
	{ SOLAREDGE_COMMAND_ACTIVATOR_LCD_TEST,					"ACTIVATOR_LCD_TEST" },
	{ SOLAREDGE_COMMAND_ACTIVATOR_BUTTONS_TEST,				"ACTIVATOR_BUTTONS_TEST" },
	{ SOLAREDGE_COMMAND_FANCONTROL_SET_PWM,					"FANCONTROL_SET_PWM" },
	{ SOLAREDGE_COMMAND_FANCONTROL_GET_PWM,					"FANCONTROL_GET_PWM" },
	{ SOLAREDGE_COMMAND_FANCONTROL_GET_ALL_PWM,				"FANCONTROL_GET_ALL_PWM" },
	{ SOLAREDGE_COMMAND_FANCONTROL_SHUT_ALL_PWM,				"FANCONTROL_SHUT_ALL_PWM" },
	{ SOLAREDGE_COMMAND_FANCONTROL_RES,					"FANCONTROL_RES" },
	{ SOLAREDGE_COMMAND_DISPLAY_BOARD_LCD_WRITE,				"DISPLAY_BOARD_LCD_WRITE" },
	{ SOLAREDGE_COMMAND_DISPLAY_BOARD_LED_SET,				"DISPLAY_BOARD_LED_SET" },
	{ 0, NULL }
};

static const value_string solaredge_data_devicetypes[] = {
	{ SOLAREDGE_DEVICETYPE_OPTIMIZER,	"Optimizer" },
	{ SOLAREDGE_DEVICETYPE_INVERTER_1PHASE,	"Single phase inverter"},
	{ SOLAREDGE_DEVICETYPE_INVERTER_3PHASE,	"Three phase inverter"},
	{ SOLAREDGE_DEVICETYPE_OPTIMIZER2,	"Optimizer" },
	{ SOLAREDGE_DEVICETYPE_EVENT,		"Wake/sleep event" },
	{ 0, NULL }
};

static gcry_cipher_hd_t cipher_hd_system;
static const char *global_system_encryption_key;

static
uint16_t calculate_crc(t_solaredge_packet_header *header, const uint8_t *data, int length)
{
	/* Concatenate in network endinaness header items followed by unmodified data */
	uint16_t crc = 0x5a5a;
	uint16_t sequence_number = g_htons(header->sequence_number);
	uint32_t source_address = g_htonl(header->source_address);
	uint32_t destination_address = g_htonl(header->destination_address);
	uint16_t command_type = g_htons(header->command_type);
	crc = crc16_plain_update(crc, (unsigned char *)&sequence_number, 2);
	crc = crc16_plain_update(crc, (unsigned char *)&source_address, 4);
	crc = crc16_plain_update(crc, (unsigned char *)&destination_address, 4);
	crc = crc16_plain_update(crc, (unsigned char *)&command_type, 2);
	return crc16_plain_update(crc, data, length);
}

static
void solaredge_decrypt(const uint8_t *in, int length, uint8_t *out, gcry_cipher_hd_t cipher)
{
	uint8_t rand1[SOLAREDGE_ENCRYPTION_KEY_LENGTH];
	uint8_t rand2[SOLAREDGE_ENCRYPTION_KEY_LENGTH];
	int payload_length = length - SOLAREDGE_ENCRYPTION_KEY_LENGTH;
	uint8_t *payload = (uint8_t *) wmem_alloc(wmem_packet_scope(), payload_length);
	uint8_t *intermediate_decrypted_payload = (uint8_t *) wmem_alloc(wmem_packet_scope(), payload_length);
	int i = 0, posa = 0, posb = 0, posc = 0;
	memcpy(rand2, in, SOLAREDGE_ENCRYPTION_KEY_LENGTH);
	memcpy(payload, in + SOLAREDGE_ENCRYPTION_KEY_LENGTH, payload_length);
	gcry_cipher_encrypt(cipher, rand1, SOLAREDGE_ENCRYPTION_KEY_LENGTH, rand2, SOLAREDGE_ENCRYPTION_KEY_LENGTH);

	for (posb = 0; posb < payload_length; posb++) {
		intermediate_decrypted_payload[posb] = payload[posb] ^ rand1[posa++];
		if (posa == 16) {
			posa = 0;
			for (posc = 15; posc >= 0; posc--) {
				rand2[posc] = (rand2[posc] + 1) & 0xFF;
				if (rand2[posc]) {
					break;
				}
			}
			gcry_cipher_encrypt(cipher, rand1, SOLAREDGE_ENCRYPTION_KEY_LENGTH, rand2, SOLAREDGE_ENCRYPTION_KEY_LENGTH);
		}
	}

	for (i  = 0; i < payload_length; i++) {
		out[i] = intermediate_decrypted_payload[i + 6] ^ intermediate_decrypted_payload[2+(i&3)];
	}
}

static int
// NOLINTNEXTLINE(misc-no-recursion)
dissect_solaredge_devicedata(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int length)
{
	int current_offset;
	t_solaredge_device_header device_header;
	proto_item *post_item;
	proto_tree *post_tree;
	const uint8_t *optimizer_data;
	float dc_voltage_panel;
	float dc_voltage_optimizer;
	float dc_current_optimizer;
	float energy_day_optimizer;
	float temperature_optimizer;
	uint32_t event_type;

	device_header.type = tvb_get_letohs(tvb, offset);
	device_header.id = tvb_get_letohl(tvb, offset + 2);
	device_header.device_length = tvb_get_letohs(tvb, offset + 6);
	post_item = proto_tree_add_item(tree, hf_solaredge_post_device_type, tvb, offset, device_header.device_length + SOLAREDGE_POST_HEADER_LENGTH, ENC_NA);
	post_tree = proto_item_add_subtree(post_item, ett_solaredge_packet_post_device);
	proto_tree_add_item(post_tree, hf_solaredge_post_device_type_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
	proto_tree_add_item(post_tree, hf_solaredge_post_device_id_type, tvb, offset + 2, 4, ENC_LITTLE_ENDIAN);
	proto_tree_add_item(post_tree, hf_solaredge_post_length_type, tvb, offset + 6, 2, ENC_LITTLE_ENDIAN);
	current_offset = offset + SOLAREDGE_POST_HEADER_LENGTH;
	col_append_str(pinfo->cinfo, COL_INFO, " ");

	increment_dissection_depth(pinfo);
	switch(device_header.type) {
		case SOLAREDGE_DEVICETYPE_OPTIMIZER:
			col_append_str(pinfo->cinfo, COL_INFO, "Optimizer");
			proto_tree_add_item(post_tree, hf_solaredge_post_optimizer_timestamp_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_optimizer_inverter_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_uint32_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_optimizer_uptime_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_optimizer_dc_voltage_panel_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_optimizer_dc_voltage_optimzer_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_optimizer_dc_current_panel_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_optimizer_energy_day_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_optimizer_temperature_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
		break;
		case SOLAREDGE_DEVICETYPE_INVERTER_1PHASE:
			col_append_str(pinfo->cinfo, COL_INFO, "Single phase inverter");
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_timestamp_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_uptime_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_interval_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_temperature_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_energy_day_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_energy_interval_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_ac_voltage_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_ac_current_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_ac_frequency_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_uint32_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_uint32_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_dc_voltage_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_uint32_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_energy_total_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_float_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_uint32_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_float_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_float_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_power_max_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_float_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_float_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_uint32_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_uint32_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_singlephase_inverter_ac_power_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_float_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_uint32_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
		break;
		case SOLAREDGE_DEVICETYPE_INVERTER_3PHASE:
			col_append_str(pinfo->cinfo, COL_INFO, "Three phase inverter");
			current_offset += device_header.device_length;
			// Not implemented yet
		break;
		case SOLAREDGE_DEVICETYPE_OPTIMIZER2:
			col_append_str(pinfo->cinfo, COL_INFO, "Optimizer");
			proto_tree_add_item(post_tree, hf_solaredge_post_optimizer_timestamp_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_optimizer_uptime_short_type, tvb, current_offset, 2, ENC_LITTLE_ENDIAN);
			current_offset += 2;
			optimizer_data = tvb_get_ptr(tvb, current_offset, 6);
			dc_voltage_panel = (float)(0.125 * (float)(optimizer_data[0] | (optimizer_data[1] << 8 & 0x300)));
			proto_tree_add_float_format_value(post_tree, hf_solaredge_post_optimizer_dc_voltage_panel_type, tvb, current_offset, 6, dc_voltage_panel, "%.2f", dc_voltage_panel);
			dc_voltage_optimizer = (float)(0.125 * (float)(optimizer_data[1] >> 2 | (optimizer_data[2] << 6 & 0x3c0)));
			proto_tree_add_float_format_value(post_tree, hf_solaredge_post_optimizer_dc_voltage_optimzer_type, tvb, current_offset, 6, dc_voltage_optimizer, "%.2f", dc_voltage_optimizer);
			dc_current_optimizer = (float)(0.00625 * (float)(optimizer_data[3] <<4 | (optimizer_data[2] >>4 & 0xf)));
			proto_tree_add_float_format_value(post_tree, hf_solaredge_post_optimizer_dc_current_optimzer_type, tvb, current_offset, 6, dc_current_optimizer, "%.2f", dc_current_optimizer);
			energy_day_optimizer = (float)(0.25 * (float)(optimizer_data[6] <<8 | optimizer_data[5]));
			proto_tree_add_float_format_value(post_tree, hf_solaredge_post_optimizer_energy_day_type, tvb, current_offset, 6, energy_day_optimizer, "%.2f", energy_day_optimizer);
			current_offset += 6;
			temperature_optimizer = (float)(2.0 * (float)tvb_get_uint8(tvb, current_offset));
			proto_tree_add_float_format_value(post_tree, hf_solaredge_post_optimizer_temperature_type, tvb, current_offset, 2, temperature_optimizer, "%.2f", temperature_optimizer);
			current_offset++;
		break;
		case SOLAREDGE_DEVICETYPE_EVENT:
			col_append_str(pinfo->cinfo, COL_INFO, "Wake/sleep event");
			proto_tree_add_item(post_tree, hf_solaredge_post_event_timestamp_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			event_type = tvb_get_uint32(tvb, current_offset, ENC_LITTLE_ENDIAN);
			proto_tree_add_item(post_tree, hf_solaredge_post_event_type_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			proto_tree_add_item(post_tree, hf_solaredge_post_event_event_start_timestamp_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			current_offset += 4;
			if (event_type == 1) {
				/* Timezone offset, then end time*/
				proto_tree_add_item(post_tree, hf_solaredge_post_event_event_timezone_offset_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
				current_offset += 4;
				proto_tree_add_item(post_tree, hf_solaredge_post_event_event_end_timestamp_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
				current_offset += 4;
			} else {
				/* End time, then unused */
				proto_tree_add_item(post_tree, hf_solaredge_post_event_event_end_timestamp_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
				current_offset += 8;
			}
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_uint32_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
			if (global_show_unknown_fields == true) {
				proto_tree_add_item(post_tree, hf_solaredge_post_padding_uint32_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
			}
			current_offset += 4;
		break;
		default:
			col_append_str(pinfo->cinfo, COL_INFO, "Unknown device");
			current_offset += device_header.device_length;
		break;
	}
	decrement_dissection_depth(pinfo);

	if (current_offset < length) {
		col_append_str(pinfo->cinfo, COL_INFO, ", ");
		dissect_solaredge_devicedata(tvb, pinfo, tree, current_offset, length);
	}
	return current_offset;
}

static int
// NOLINTNEXTLINE(misc-no-recursion)
dissect_solaredge_recursive(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_, int ett, conversation_t *conv)
{
	proto_item *ti;
	proto_tree *solaredge_header_tree;
	proto_item *solaredge_payload_item;
	proto_tree *solaredge_payload_tree;
	int32_t current_offset = 0;
	t_solaredge_packet_header header;
	GByteArray *system_key;
	uint8_t session_key_message_part1[SOLAREDGE_ENCRYPTION_KEY_LENGTH];
	uint8_t session_key_message_part2[SOLAREDGE_ENCRYPTION_KEY_LENGTH];
	uint8_t session_key_intermediate[SOLAREDGE_ENCRYPTION_KEY_LENGTH];
	unsigned i;
	t_solaredge_conversion_data *conv_data;
	bool system_key_valid;

	/* Starts with magic number */
	if ( tvb_get_uint32(tvb, 0, ENC_LITTLE_ENDIAN) != SOLAREDGE_MAGIC_NUMBER) {
		return 0;
	}
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "SolarEdge");
	col_clear(pinfo->cinfo,COL_INFO);
	ti = proto_tree_add_item(tree, proto_solaredge, tvb, 0, -1, ENC_NA);
	current_offset += 4;
	solaredge_header_tree = proto_item_add_subtree(ti, ett);

	header.length = tvb_get_uint16(tvb, current_offset, ENC_LITTLE_ENDIAN);
	proto_tree_add_item(solaredge_header_tree, hf_solaredge_length_type, tvb, current_offset, 2, ENC_LITTLE_ENDIAN);
	current_offset += 2;
	header.length_inverse = tvb_get_uint16(tvb, current_offset, ENC_LITTLE_ENDIAN);
	if (header.length_inverse != (UINT16_MAX - header.length)) {
		proto_tree_add_expert_format(solaredge_header_tree, pinfo, &ei_solaredge_invalid_length, tvb, current_offset - 2, current_offset + 2, "Invalid length: inverse length %d not matching length %d", header.length_inverse, header.length);
	}
	proto_tree_add_item(solaredge_header_tree, hf_solaredge_length_inverse_type, tvb, current_offset, 2, ENC_LITTLE_ENDIAN);
	current_offset += 2;
	header.sequence_number = tvb_get_uint16(tvb, current_offset, ENC_LITTLE_ENDIAN);
	proto_tree_add_item(solaredge_header_tree, hf_solaredge_sequence_number_type, tvb, current_offset, 2, ENC_LITTLE_ENDIAN);
	current_offset += 2;
	header.source_address = tvb_get_uint32(tvb, current_offset, ENC_LITTLE_ENDIAN);
	proto_tree_add_item(solaredge_header_tree, hf_solaredge_source_address_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
	current_offset += 4;
	header.destination_address = tvb_get_uint32(tvb, current_offset, ENC_LITTLE_ENDIAN);
	proto_tree_add_item(solaredge_header_tree, hf_solaredge_destination_address_type, tvb, current_offset, 4, ENC_LITTLE_ENDIAN);
	current_offset += 4;
	header.command_type = tvb_get_uint16(tvb, current_offset, ENC_LITTLE_ENDIAN);
	proto_tree_add_item(solaredge_header_tree, hf_solaredge_command_type, tvb, current_offset, 2, ENC_LITTLE_ENDIAN);
	current_offset += 2;
	col_append_str(pinfo->cinfo, COL_INFO, val_to_str_const(header.command_type, solaredge_packet_commandtypes, "Unknown command"));

	increment_dissection_depth(pinfo);
	switch (header.command_type) {
		case SOLAREDGE_COMMAND_MISC_ENCRYPTED:
			proto_tree_add_item(solaredge_header_tree, hf_solaredge_payload_type, tvb, current_offset, header.length, ENC_NA);
			conv_data = (t_solaredge_conversion_data *)conversation_get_proto_data(conv, proto_solaredge);
			if ((conv_data != NULL) && (conv_data->session_key_found == true)) {
				uint8_t *decrypted_buffer = (uint8_t*)wmem_alloc(pinfo->pool, header.length);
				solaredge_decrypt(tvb_get_ptr(tvb, current_offset, header.length), header.length, decrypted_buffer, conv_data->cipher_hd_session);
				tvbuff_t *next_tvb = tvb_new_child_real_data(tvb, decrypted_buffer, header.length, header.length);
				if ( tvb_get_uint32(next_tvb, 0, ENC_LITTLE_ENDIAN) == SOLAREDGE_MAGIC_NUMBER) {
					add_new_data_source(pinfo, next_tvb, "Decrypted Packet");
					dissect_solaredge_recursive(next_tvb, pinfo, tree, data, ett_solaredge_packet_decrypted, conv);
				}
			}
			current_offset += header.length;
		break;
		case SOLAREDGE_COMMAND_SERVER_POST_DATA:
			solaredge_payload_item = proto_tree_add_item(solaredge_header_tree, hf_solaredge_post_type, tvb, current_offset, header.length, ENC_NA);
			solaredge_payload_tree = proto_item_add_subtree(solaredge_payload_item, ett_solaredge_packet_post);
			dissect_solaredge_devicedata(tvb, pinfo, solaredge_payload_tree, current_offset, header.length);
		break;
		case SOLAREDGE_COMMAND_SERVER_SET_KEY:
			proto_tree_add_item(solaredge_header_tree, hf_solaredge_session_key_type, tvb, current_offset, header.length, ENC_NA);
			if (!gcry_cipher_open(&cipher_hd_system, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, 0)) {
				/* Load the system key to generate session key */
				system_key = g_byte_array_new();
				system_key_valid = hex_str_to_bytes(global_system_encryption_key, system_key, false);
				if ((system_key_valid == true) && (system_key->len == SOLAREDGE_ENCRYPTION_KEY_LENGTH)) {
					if (!gcry_cipher_setkey(cipher_hd_system, system_key->data, SOLAREDGE_ENCRYPTION_KEY_LENGTH)) {
						/* Read first part of message */
						tvb_memcpy(tvb, session_key_message_part1, current_offset, SOLAREDGE_ENCRYPTION_KEY_LENGTH);
						current_offset += SOLAREDGE_ENCRYPTION_KEY_LENGTH;
						/* Read second part of message */
						tvb_memcpy(tvb, session_key_message_part2, current_offset, SOLAREDGE_ENCRYPTION_KEY_LENGTH);
						current_offset += SOLAREDGE_ENCRYPTION_KEY_LENGTH;
						/* Encrypt first part with system key */
						gcry_cipher_encrypt(cipher_hd_system, session_key_intermediate, SOLAREDGE_ENCRYPTION_KEY_LENGTH, session_key_message_part1, SOLAREDGE_ENCRYPTION_KEY_LENGTH);
						/* XOR result with second part to obtain session key */
						for (i = 0; i < SOLAREDGE_ENCRYPTION_KEY_LENGTH; i++) {
							session_key_message_part2[i] = session_key_intermediate[i] ^ session_key_message_part2[i];
						}
						conv_data = (t_solaredge_conversion_data *)conversation_get_proto_data(conv, proto_solaredge);
						if (!gcry_cipher_open(&conv_data->cipher_hd_session, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, 0)) {
							/* Load the session key */
							if (!gcry_cipher_setkey(conv_data->cipher_hd_session, session_key_message_part2, SOLAREDGE_ENCRYPTION_KEY_LENGTH)) {
								conv_data->session_key_found = true;
							} else {
								gcry_cipher_close(conv_data->cipher_hd_session);
							}
						}
					}
					gcry_cipher_close(cipher_hd_system);
				}
			}
		break;
		default:
			/* If not implemented, skip command */
			current_offset += header.length;
		break;
	}
	decrement_dissection_depth(pinfo);

	/* Validate CRC */
	proto_tree_add_checksum(solaredge_header_tree, tvb, SOLAREDGE_HEADER_LENGTH + header.length, hf_solaredge_crc_type, hf_solaredge_crc_status_type, &ei_solaredge_invalid_crc, pinfo, calculate_crc(&header, tvb_get_ptr(tvb, SOLAREDGE_HEADER_LENGTH, header.length), header.length), ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
	current_offset += 2;
	return current_offset;
}

static int
dissect_solaredge(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_)
{
	conversation_t *conv = find_or_create_conversation(pinfo);
	t_solaredge_conversion_data *conv_data;
	if (conversation_get_proto_data(conv, proto_solaredge) == NULL) {
		/* Setup empty encryption key */
		conv_data = wmem_new(wmem_file_scope(), t_solaredge_conversion_data);
		conv_data->session_key_found = false;
		conversation_add_proto_data(conv, proto_solaredge, conv_data);
	}
	return dissect_solaredge_recursive(tvb, pinfo, tree, data, ett_solaredge_packet, conv);
}

void
proto_reg_handoff_solaredge(void)
{
	dissector_add_for_decode_as("tcp.port", solaredge_handle);
}

void
proto_register_solaredge(void)
{
	static hf_register_info hf[] = {
	{ &hf_solaredge_length_type,
		{ "Length", "solaredge.length",
		FT_UINT16, BASE_DEC,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_length_inverse_type,
		{ "Length inverse", "solaredge.length_inverse",
		FT_UINT16, BASE_DEC,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_sequence_number_type,
		{ "Sequence number", "solaredge.sequence_number",
		FT_UINT16, BASE_DEC,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_source_address_type,
		{ "Source address", "solaredge.source_address",
		FT_UINT32, BASE_HEX,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_destination_address_type,
		{ "Destination address", "solaredge.destination_address",
		FT_UINT32, BASE_HEX,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_command_type,
		{ "Command Type", "solaredge.command",
		FT_UINT16, BASE_HEX,
		VALS(solaredge_packet_commandtypes), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_crc_type,
		{ "CRC", "solaredge.crc",
		FT_UINT16, BASE_HEX,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_crc_status_type,
		{ "CRC Status", "solaredge.crc.status",
		FT_UINT8, BASE_NONE,
		VALS(proto_checksum_vals), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_payload_type,
		{ "Payload", "solaredge.payload",
		FT_BYTES, BASE_NONE,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_session_key_type,
		{ "Session key", "solaredge.session_key",
		FT_BYTES, BASE_NONE,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_type,
		{ "Post data", "solaredge.post",
		FT_NONE, BASE_NONE,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_device_type,
		{ "Device", "solaredge.post.device",
		FT_NONE, BASE_NONE,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_device_type_type,
		{ "Device Type", "solaredge.post.device.type",
		FT_UINT16, BASE_HEX,
		VALS(solaredge_data_devicetypes), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_device_id_type,
		{ "Device ID", "solaredge.post.device.id",
		FT_UINT32, BASE_HEX,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_length_type,
		{ "Length", "solaredge.post.device.length",
		FT_UINT16, BASE_DEC,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_padding_uint32_type,
		{ "Padding (uint32)", "solaredge.post.device.padding_uint32",
		FT_UINT32, BASE_HEX,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_padding_float_type,
		{ "Padding (float)", "solaredge.post.device.padding_float",
		FT_FLOAT, BASE_NONE,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_timestamp_type,
		{ "Timestamp", "solaredge.post.device.singlephase_inverter.timestamp",
		FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_uptime_type,
		{ "Uptime", "solaredge.post.device.singlephase_inverter.uptime",
		FT_RELATIVE_TIME, BASE_NONE,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_interval_type,
		{ "Interval", "solaredge.post.device.singlephase_inverter.interval",
		FT_UINT32, BASE_DEC,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_temperature_type,
		{ "Temperature", "solaredge.post.device.singlephase_inverter.temperature",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_degree_celsius), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_energy_day_type,
		{ "Energy current day", "solaredge.post.device.singlephase_inverter.energy_day",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_watthour), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_energy_interval_type,
		{ "Energy current interval", "solaredge.post.device.singlephase_inverter.energy_interval",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_watthour), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_ac_voltage_type,
		{ "AC Voltage", "solaredge.post.device.singlephase_inverter.ac_voltage",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_volt), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_ac_current_type,
		{ "AC Current", "solaredge.post.device.singlephase_inverter.ac_current",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_amp), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_ac_frequency_type,
		{ "AC Frequency", "solaredge.post.device.singlephase_inverter.ac_frequency",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_hz), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_dc_voltage_type,
		{ "DC Voltage", "solaredge.post.device.singlephase_inverter.dc_voltage",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_volt), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_energy_total_type,
		{ "Energy total", "solaredge.post.device.singlephase_inverter.energy_total",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_watthour), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_power_max_type,
		{ "Power Max", "solaredge.post.device.singlephase_inverter.power_max",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_watt), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_singlephase_inverter_ac_power_type,
		{ "AC Power", "solaredge.post.device.singlephase_inverter.ac_power",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_watt), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_optimizer_inverter_type,
		{ "Inverter ID", "solaredge.post.device.optimizer.inverter",
		FT_UINT32, BASE_HEX,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_optimizer_dc_current_panel_type,
		{ "DC Current Panel", "solaredge.post.device.optimizer.panel_dc_current",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_amp), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_optimizer_timestamp_type,
		{ "Timestamp", "solaredge.post.device.optimizer.timestamp",
		FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_optimizer_uptime_type,
		{ "Uptime", "solaredge.post.device.optimizer.uptime",
		FT_RELATIVE_TIME, BASE_NONE,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_optimizer_uptime_short_type,
		{ "Uptime (short format)", "solaredge.post.device.optimizer.uptime_short",
		FT_UINT16, BASE_DEC,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_optimizer_dc_voltage_panel_type,
		{ "DC Voltage Panel", "solaredge.post.device.optimizer.panel_dc_voltage",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_volt), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_optimizer_dc_voltage_optimzer_type,
		{ "DC Voltage Optimizer", "solaredge.post.device.optimizer.optimizer_dc_voltage",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_volt), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_optimizer_dc_current_optimzer_type,
		{ "DC Current Optimizer", "solaredge.post.device.optimizer.optimizer_dc_current",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_amp), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_optimizer_energy_day_type,
		{ "Energy current day", "solaredge.post.device.optimizer.energy_day",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_watthour), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_optimizer_temperature_type,
		{ "Temperature", "solaredge.post.device.optimizer.temperature",
		FT_FLOAT, BASE_NONE|BASE_UNIT_STRING,
		UNS(&units_degree_celsius), 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_event_timestamp_type,
		{ "Timestamp", "solaredge.post.device.event.timestamp",
		FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_event_type_type,
		{ "Type", "solaredge.post.device.event.type",
		FT_UINT32, BASE_HEX,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_event_event_start_timestamp_type,
		{ "Event start", "solaredge.post.device.event.start",
		FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_event_event_timezone_offset_type,
		{ "Timezone offset", "solaredge.post.device.event.timezone_offset",
		FT_INT32, BASE_DEC,
		NULL, 0x0,
		NULL, HFILL }
	},
	{ &hf_solaredge_post_event_event_end_timestamp_type,
		{ "Event stop", "solaredge.post.device.event.stop",
		FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
		NULL, 0x0,
		NULL, HFILL }
	},
	};

	static ei_register_info ei[] = {
		{ &ei_solaredge_invalid_length, { "solaredge.invalid_length", PI_MALFORMED, PI_WARN, "Inverse length field not matching length field", EXPFILL }},
		{ &ei_solaredge_invalid_crc, { "solaredge.invalid_crc", PI_CHECKSUM, PI_WARN, "CRC does not match data", EXPFILL }}
	};

	expert_module_t* expert_solaredge;

	/* Setup protocol subtree array */
	static int *ett[] = {
		&ett_solaredge_packet,
		&ett_solaredge_packet_decrypted,
		&ett_solaredge_packet_post,
		&ett_solaredge_packet_post_device
	};

	proto_solaredge = proto_register_protocol ("SolarEdge monitoring protocol", "SolarEdge", "solaredge");
	solaredge_handle = register_dissector("solaredge", dissect_solaredge, proto_solaredge);

	module_t * module_solaredge = prefs_register_protocol(proto_solaredge, NULL);
	prefs_register_bool_preference(module_solaredge, "unknown", "Show unknown fields", "Show unidentified fields (\"padding\") in packet dissections", &global_show_unknown_fields);
	prefs_register_string_preference(module_solaredge, "system_encryption_key", "System encryption key", "Inverter system encryption key", &global_system_encryption_key);

	proto_register_field_array(proto_solaredge, hf, array_length(hf));
	proto_register_subtree_array(ett, array_length(ett));

	expert_solaredge = expert_register_protocol(proto_solaredge);
	expert_register_field_array(expert_solaredge, ei, array_length(ei));
}

/*
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
 *
 * Local variables:
 * c-basic-offset: 8
 * tab-width: 8
 * indent-tabs-mode: t
 * End:
 *
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
 * :indentSize=8:tabSize=8:noTabs=false:
 */
